收藏
回答

微信公众号消息加解密为何在验签时失败?

我们需要在公众号中对收发的消息进行加密,在公众号中设置了兼容模式进行调试根据文档https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Message_encryption_and_decryption_instructions.html下载了demo,demo可以正常运行,但是如果把其中的参数改成我们公众号自己的参数,解密时在验签步骤就失败了,代码运行后得到的signature和附带的signature不一样,导致验签失败。

我们使用的语言是C#,原本的代码如下:

//公众平台上开发者设置的token, appID, EncodingAESKey
string sToken = "QDG6eK";
string sAppID = "wx5823bf96d3bd56c7";
string sEncodingAESKey = "jWmYm7qr5nMoAUwZRjGtBxmz3KA1tkAj3ykkR6q2B2C";


Tencent.WXBizMsgCrypt wxcpt = new Tencent.WXBizMsgCrypt(sToken, sEncodingAESKey, sAppID);


/* 1. 对用户回复的数据进行解密。
* 用户回复消息或者点击事件响应时,企业会收到回调消息,假设企业收到的推送消息:
* 	POST /cgi-bin/wxpush? msg_signature=477715d11cdb4164915debcba66cb864d751f3e6×tamp=1409659813&nonce=1372623149 HTTP/1.1
   Host: qy.weixin.qq.com
   Content-Length: 613
*
* 	
	   
	   
   
*/
string sReqMsgSig = "477715d11cdb4164915debcba66cb864d751f3e6";
string sReqTimeStamp = "1409659813";
string sReqNonce = "1372623149";
string sReqData = "";


string sMsg = ""//解析之后的明文
int ret = 0;
ret = wxcpt.DecryptMsg(sReqMsgSig, sReqTimeStamp, sReqNonce, sReqData, ref sMsg);
if (ret != 0)
{
	System.Console.WriteLine("ERR: Decrypt fail, ret: " + ret);
	return;
}
System.Console.WriteLine(sMsg);


当把其中的参数sToken,sAppID,sEncodingAESKey,sReqMsgSig,sReqTimeStamp,sReqNonce,sReqData替换成真实推送过来的参数,验签步骤就失败了,失败的原因是代码生成的signature和传递过来的signature不一致

ret = VerifySignature(m_sToken, sTimeStamp, sNonce, sEncryptMsg, sMsgSignature);


private static int VerifySignature(string sToken, string sTimeStamp, string sNonce, string sMsgEncrypt, string sSigture)
        {
            string hash = "";
            int ret = 0;
            ret = GenarateSinature(sToken, sTimeStamp, sNonce, sMsgEncrypt, ref hash);
            if (ret != 0)
                return ret;
            //System.Console.WriteLine(hash);
            if (hash == sSigture)
                return 0;
            else
            {
                return (int)WXBizMsgCryptErrorCode.WXBizMsgCrypt_ValidateSignature_Error;
            }
        }

返回的ret结果是-40001,尝试过sToken使用token的名称或者最新的值,都在验签步骤失败,一样的错误。

根据文档https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/2.0/api/Before_Develop/Technical_Plan.html,消息解密需要用到的数据有timestamp, nonce, msg_signature(来自request.querystring), Encrypt Message(来自Request.InputStream中的密文消息体Encrypt节点), Token(微信开放平台上,服务方设置的接收消息的校验 token)。 验签时根据Token, timestamp, nonce, Encrypt生成signature, 和msg_signature比对完成验签。

请问问题出在哪里?是哪个参数没有设置好?

已解决,是Token参数使用错了,用的是AccessToken,导致生成的签名不一致,使用公众号中设置的Token名称即可。


最后一次编辑于  05-11
回答关注问题邀请回答
收藏

3 个回答

  • 社区技术运营专员--许涛
    社区技术运营专员--许涛
    04-10

    你好,是否有返回rid呢?

    04-10
    有用
    回复 5
    • 华府高级伴读小书童
      华府高级伴读小书童
      04-11
      你好,是在VerifySignature的时候出问题了,使用GenarateSinature(sToken, sTimeStamp, sNonce, sMsgEncrypt, ref hash)返回的signature和传递过来的signature不一致。我不知道你说的rid是指什么。
      04-11
      回复
    • 社区技术运营专员--许涛
      社区技术运营专员--许涛
      04-11回复华府高级伴读小书童
      40001
      04-11
      回复
    • 华府高级伴读小书童
      华府高级伴读小书童
      04-12回复社区技术运营专员--许涛
      这里的返回值是代码中自己定义的,和全局返回码无关。这里返回的-40001意思就是验签失败
      enum WXBizMsgCryptErrorCode
              {
                  WXBizMsgCrypt_OK = 0,
                  WXBizMsgCrypt_ValidateSignature_Error = -40001,
                  WXBizMsgCrypt_ParseXml_Error = -40002,
                  WXBizMsgCrypt_ComputeSignature_Error = -40003,
                  WXBizMsgCrypt_IllegalAesKey = -40004,
                  WXBizMsgCrypt_ValidateAppid_Error = -40005,
                  WXBizMsgCrypt_EncryptAES_Error = -40006,
                  WXBizMsgCrypt_DecryptAES_Error = -40007,
                  WXBizMsgCrypt_IllegalBuffer = -40008,
                  WXBizMsgCrypt_EncodeBase64_Error = -40009,
                  WXBizMsgCrypt_DecodeBase64_Error = -40010
              };
      04-12
      回复
    • 社区技术运营专员--许涛
      社区技术运营专员--许涛
      04-12回复华府高级伴读小书童
      所以问题点是自己定义的返回码,不知道为什么出现这个错误吗?
      04-12
      回复
    • 华府高级伴读小书童
      华府高级伴读小书童
      05-10回复社区技术运营专员--许涛
      问题点是微信文档里提供的demo,替换成自己的数据,加密的消息验签通不过
      05-10
      回复
  • 华府高级伴读小书童
    华府高级伴读小书童
    05-11

    找到原因了,是参数Token,使用错误,应该使用微信公众号->基本配置->服务器配置里的令牌(Token), 而不是每两小时刷新一次的accesstoken

    05-11
    有用
    回复
  • jims
    jims
    04-15

    问题解决了吗?我这边也遇到同样的问题,直接是下周微信提供的demo。

    04-15
    有用
    回复 3
登录 后发表内容