报错:状态码401或者“错误的签名,验签失败”或者“签名错误,请检查后再试”
更新时间:2024.08.22建议开发者先参考如何计算签名和如何验证签名系列文档,一步步按照示例操作,熟悉签名计算过程,解决签名问题。
如果出现以上报错则说明是签名计算错误,请按照以下步骤排查:
1、如果你是服务商,则签名时需要用服务商的商户API私钥而不是子商户的API私钥
2、计算签名的时候用的是商户API私钥(apiclient_key.pem)文件,你可以通过文件名做初步的甄别,请确认你使用的是正确的文件,常见的错误使用方式有以下几种:
(1)使用了商户API证书(apiclient_cert.pem)文件而不是商户API私钥(apiclient_key.pem),这两个文件的名字非常相似,请注意不要搞混
(2)使用了平台证书(wechatpay.pem)的公钥文件,而不是商户API私钥(apiclient_key.pem)
请确认你是参考了如何下载商户API证书 (opens new window),获取了商户API证书(apiclient_cert.pem)和商户API私钥(apiclient_key.pem)
3、计算签名时,你需要用到商户API私钥(apiclient_key.pem)文件去计算签名串,同时你需要通过HTTP Authorization头来传递签名,Authorization头部会涉及商户号(mchid)、商户API证书的序列号(serial_no)请确认商户API私钥(apiclient_key.pem)、商户号(mchid)和商户API证书(apiclient_cert.pem)的序列号(serial_no)是一一对应的关系,请按照以下步骤排查
举例说明:
1Authorization: WECHATPAY2-SHA256-RSA2048 mchid="1900007291",nonce_str="593BEC0C930BF1AFEB40B4A08C8FB242",signature="gZGkLF3mVIHY72hE1cFSrbEOKr5O7N2jYZAt5VSBpZpHn84HWylnljJHGGlMAtFt4AUP/gso9MyQ95GNb9h9DYI3RmwQe2kvcysVKoYvzgst217AzZYYwHaUnanaEFEuKD33L84JPe/HX1CLs4VjcE16aZfORqHanlgPivirKg/SysHWtlHVU5zYiWsfXU3ylgWXqjj4hHRgKiJ1KbPzMqS0izDfnEBfTWp7GQddnxVOcbCGfk6jQECNu5GX9hFoxL2oCv5iHUg5Vka0/rKs9wjlRLmDPyObMpJUYQ2/a7HcNnzFxxC+JJa+PAjLWT/nkEMdTMotHFwQN05TWB0M9A==%",timestamp="1554208460",serial_no="1DDE55AD98ED71D6EDD4A4A16996DE7B47773A8C"
(1)确认你使用的商户API证书(apiclient_cert.pem)和商户API证书序列号是一致的,可以用openssl命令行工具查看商户API证书序列号
1openssl x509 -in apiclient_cert.pem -noout -serial
你会得到商户API证书序列号,确认你得到的序列号和Authorization头部传的serial_no字段是一致的
1serial=1DDE55AD98ED71D6EDD4A4A16996DE7B47773A8C
(2)确认你的商户号(mchid)和商户API证书(apiclient_cert.pem)也是匹配的,可以用openssl命令行工具查看证书对应的商户号
1openssl x509 -in apiclient_cert.pem -noout -text | grep -o 'CN=[0-9]*' | sed 's/CN=//'
你会得到商户号(mchid),确认你得到的序列号和Authorization头部传的mchid字段是一致的
11900007291
4、HTTP Authorization头里传递的随机字符串(nonce_str)和时间戳(timestamp)字段和你计算签名时的传的值不一致
举例说明:如下图,计算签名是用的时间戳和随机字符串必须和HTTP Authorization头里传递的随机字符串(nonce_str)和时间戳(timestamp)保持一致
5、签名串格式问题
(1)计算签名时没有正确处理\n,格式不正确,签名示例里\n是换行符而不是一个字符,请确认计算签名时有正确处理\n
(2)第一行的请求方法必须要用大写字母,比如GET,POST,PUT而不能是小写字母的get,post,put
(3)生成请求签名共5行,每一行都以换行符结尾,如果是get请求请注意第五行是空行加换行符,请不要遗漏换行符
(4)请确认第二行的URL正常替换成你的要请求的接口的url,而不是文档示例里的URL,且不带域名格式的,一定是/v3/certificates格式,而不是https://api.mch.weixin.qq.com/v3/certificates格式
(5)请检查你的签名串里没有多余的/,比如不要出现//v3/certificates
7、以上确认都无问题,依然存在签名报错问题,则很有可能是因为代码处理上做了转义,你可以使用你的代码并用示例里的密钥和示例请求计算一遍签名值,如果代码计算出来的签名值和示例里的不一致,则请检查你的代码的转义问题
可以参考 操作指引-如何生成请求签名 和 操作指引-如何验证签名 系列文档