代码 支付宝加签验签失败排查:isv.invalid-signature、证书模式 sub_code 与 SDK 报错对照

2026-10-08 09:01:24

支付宝加签验签失败排查:isv.invalid-signature、证书模式 sub_code 与 SDK 报错对照

对接支付宝开放平台时,请求加签和响应验签是两条独立链路。请求加签用商户应用私钥,平台用上传的应用公钥验;响应验签用支付宝私钥签,商户用支付宝公钥验。下面按报错原文、待签名串、签名方式、证书升级、密钥匹配五段整理。sub_code 与 SDK 异常来自官方文档,可直接查;涉及具体版本、SDK 方法名和实际待签名串的,需要在你自己的环境里抓日志核对。

一、按 sub_code 和 SDK 异常定位

官方自助排查签名验签问题给出的映射关系:

{"code":"40003","msg":"Insufficient Conditions","sub_code":"isv.missing-signature-config","sub_msg":"验签出错, 未配置对应签名算法的公钥或者证书"}

开放平台没有配置商家公钥。

{"code":"40002","msg":"Invalid Arguments","sub_code":"isv.invalid-signature","sub_msg":"无效签名"}

签名校验失败。按四项检查:网关地址是生产还是沙箱,必须用与之匹配的 app_id 与私钥;charset 是否正确;私钥与开放平台上传的应用公钥是否匹配;sign_type 是否正确(不传默认 RSA)。

证书模式下还有两个:

  • {"code":"40002","sub_code":"isv.missing-app-cert-sn","sub_msg":"缺少应用公钥证书序列号"}:请求参数缺少 app_cert_sn。
  • {"code":"40002","sub_code":"isv.app-cert-not-exist","sub_msg":"应用公钥证书不存在"}:指定的应用公钥证书未上传。

SDK 侧常见异常:

  • alipayPublicKey should not be NULL:代码里支付宝公钥参数未赋值。
  • java.security.InvalidKeyException:支付宝公钥内容错误。
  • sign check fail: check Sign and Data Fail:支付宝返回内容验签失败,属于响应验签,不是请求加签。检查 gateway 是否与 app_id / 支付宝公钥匹配、charset、代码里支付宝公钥与平台获取的是否一致。
  • Caused by: java.security.SignatureException: Signature length not correct: got 256 but was expecting 128:支付宝公钥与 sign_type 不匹配。RSA2 用 2048 位签名、256 字节;RSA 用 1024 位、128 字节。sign_type=RSA2 必须配 RSA2 对应的支付宝公钥,不能拿 RSA 类型下的公钥顶。

二、待签名串与提交方法

验签失败时,报错报文里会带上网关生成的待验签字符串,官方验签排查 FAQ给出的示例形如:

网关生成的验签字符串为:alipay_sdk=...&app_id=...&biz_content={...}&charset=UTF-8&format=json&method=alipay.trade.precreate&notify_url=...&sign_type=RSA&timetamp=2020-07-28 11:23:32&version=1.0

从这段能看出参与签名的字段列表和顺序,用来对照自己拼的串。

官方列出的原因:密钥不匹配、编码格式不统一、请求参数数据有误、调用加签方式和应用上选择的加签方式不对应、SDK 调用提交方法有误、SDK 运行环境有误。其他都排掉之后,重点查密钥不匹配。

签名方式按应用「接口加签方式」里选的模式走。公钥证书比普通公钥多了 alipay_root_cert_sn 和 app_cert_sn 参与签名。资金类接口(单笔转账到支付宝账户、现金红包)强制校验是否用公钥证书签名,用公钥方式会被拒,需要改公钥证书模式。

SDK 提交方法在证书模式下要换:Java execute() → certificateExecute(),.Net execute() → CertificateExecute(),PHP 仍然用 execute()。pageExecute / sdkExecute 两者一致,不用改。

待签名串的三条硬要求:去掉值为空的参数;所有参数按字母升序排序;签名后对所有参数值做 url encode 再发起请求。

三、普通 RSA2 与公钥证书的配置差异

签名交互固定:商户应用私钥签请求参数,商户应用公钥上传平台供平台验请求,平台用支付宝私钥签结果,商户用支付宝公钥验回调。官方确定签名方式列了两套配置。

普通 RSA2 需要配 gateway、app_id、应用私钥 private_key、charset、支付宝公钥 alipay_public_key、sign_type。密钥形态要区分:rsa_private_key(pkcs1,PHP / .Net)、rsa_private_key_pkcs8(Java / Android / iOS)、rsa_public_key 上传到平台、alipay_public_key 留在本地。

公钥证书模式需要配 app_id、应用私钥、应用公钥证书路径 app_cert_path、支付宝公钥证书路径 alipay_cert_path、支付宝 CA 根证书路径 alipay_root_cert_path、charset、sign_type。

四、密钥升级证书后的 7 天窗口

开放平台证书升级指南写明:加签方式由密钥升级为证书、或更新证书,走开放平台的「变更」操作。变更后新加签方式立即生效,旧加签方式 7 天后失效,必须在这 7 天内更新网关访问代码里的密钥配置,否则旧方式的请求会被网关拦截。也可以「立即作废」让旧方式实时失效,或「撤销变更」回滚。

证书模式下,XML / JSON 响应报文里多了 app_cert_sn(应用公钥证书序列号),注意 app_cert_sn 不参与签名。支付宝在已上传的应用公钥证书里找匹配证书对响应验签。

SDK 支持证书模式的最低版本:Java 4.4.5.ALL+、PHP 4.1.0+、.Net 4.0.0+、NodeJS 3.1.1+,其它语言 SDK 还不支持。版本号要在 pom.xml / composer.json 等依赖文件里核实,不靠记忆。

五、校验应用私钥与应用公钥是否匹配

按如何检验密钥证书是否匹配,用「支付宝开放平台开发助手」的「密钥匹配」功能:填商户应用私钥,加上从「应用公钥证书」下载并解析出的应用公钥值。PHP 解析出的应用公钥值中间可能带换行或空格,要先去掉空格拼成一行再填。

前提、不适用与未解点

前提:已经拿到应用私钥、支付宝公钥或证书文件,并且能改网关访问代码。不适用:不覆盖生活号 / 小程序端签名,也不解决账户权限和产品签约问题。

未解点:错误示例里的字段顺序与 timetamp 这类拼写,取决于你的 SDK 版本,需抓实际待签名串确认;证书变更被网关拦截时返回的具体错误码,本文没有给出;Java / PHP / .Net / NodeJS 之外的语言,官方目前没有证书模式 SDK。

参考

推荐文章

程序员茄子在线接单