{"record":{"id":"11c25c0b85319c43","repo":"JeffreySu/WeiXinMPSDK","slug":"rsa-tenpaysignhelper","errorCode":null,"errorMessage":"证书中未包含 RSA 公钥。","messagePattern":"证书中未包含 RSA 公钥。","errorType":"exception","errorClass":"CryptographicException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Helpers/TenPaySignHelper.cs","lineNumber":224,"sourceCode":"\n            if (certType == CertType.SM)\n            {\n                byte[] pubKeyBytes = Convert.FromBase64String(pubKey);\n                ECPublicKeyParameters eCPublicKeyParameters = SMPemHelper.LoadPublicKeyToParameters(pubKeyBytes);\n                return GmHelper.VerifySm3WithSm2(eCPublicKeyParameters, contentForSign, wechatpaySignatureBase64);\n            }\n            else\n            {\n                //Base64 解码 pubKey（必须已经使用 ApiSecurityHelper.GetUnwrapCertKey() 方法进行 Unwrap）\n                var bs = Convert.FromBase64String(pubKey);\n                //使用 X509Certificate2 证书\n                using (var x509 = new X509Certificate2(bs))\n                using (var key = x509.GetRSAPublicKey())\n                using (var sha256 = SHA256.Create())\n                {\n                    if (key == null)\n                    {\n                        throw new CryptographicException(\"证书中未包含 RSA 公钥。\");\n                    }\n\n                    //RSAPKCS1SignatureDeformatter 对象\n                    RSAPKCS1SignatureDeformatter df = new RSAPKCS1SignatureDeformatter(key);\n                    //指定 SHA256\n                    df.SetHashAlgorithm(\"SHA256\");\n                    //应答签名\n                    byte[] signature = Convert.FromBase64String(wechatpaySignatureBase64);\n                    //对比签名\n                    byte[] compareByte = sha256.ComputeHash(Encoding.UTF8.GetBytes(contentForSign));\n                    //验证签名\n                    return df.VerifySignature(compareByte, signature);\n                }\n            }\n        }\n\n        /// <summary>\n        /// 检验签名，以确保回调是由微信支付发送。","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Helpers/TenPaySignHelper.cs#L206-L242","documentation":"TenPaySignHelper.VerifyTenpaySign verifies WeChat Pay signatures with the platform certificate's RSA public key (RSAPKCS1SignatureDeformatter + SHA256). If the certificate has no RSA public key (GetRSAPublicKey() null), CryptographicException \"证书中未包含 RSA 公钥。\" is thrown.","triggerScenarios":"Verifying a WeChat Pay callback/response signature using a certificate whose key is EC/SM2 instead of RSA, or a malformed certificate that parses without an RSA key.","commonSituations":"Merchants switched to SM2 certificates/public-key mode but still using the RSA verification path, or passing the wrong cert content (e.g. a public key PEM rather than an X509 cert).","solutions":["Pass a base64/DER platform certificate containing an RSA public key.","If the merchant uses SM2, use the SM2 verification path instead of VerifyTenpaySign.","Pre-check new X509Certificate2(bytes).GetRSAPublicKey() != null before verifying.","Refresh platform certificates from WeChat Pay and ensure you use the current one."],"exampleFix":"// before\nvar ok = TenPaySignHelper.VerifyTenpaySign(sm2Cert, message, signature);\n// after\nusing var x509 = new X509Certificate2(rsaCertBytes);\nif (x509.GetRSAPublicKey() == null) throw new InvalidOperationException(\"需要 RSA 平台证书\");\nvar ok = TenPaySignHelper.VerifyTenpaySign(rsaCertBase64, message, signature);","handlingStrategy":"validation","validationCode":"bool CanVerifyWithRsa(string certBase64) {\n    using var x509 = new X509Certificate2(Convert.FromBase64String(certBase64));\n    return x509.GetRSAPublicKey() != null;\n}","typeGuard":null,"tryCatchPattern":"try { var ok = TenPaySignHelper.VerifyTenpaySign(cert, message, signature); }\ncatch (CryptographicException ex) { logger.Error(ex, \"平台证书无 RSA 公钥\"); }","preventionTips":["Keep current RSA platform certificates downloaded and refreshed","Route SM2 merchants to the SM2 verification path","Verify cert key algorithm before signature verification"],"tags":["cryptography","rsa","signature-verification","wechat-pay"],"backgroundTag":"invalid-argument-value","analyzedSha":"be573f6f94bdbf718dd5f6cdecb137fbc7ff651e","analyzedAt":"2026-09-12T10:01:50.733Z","contentChangedAt":"2026-09-12T10:01:50.733Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}