JeffreySu/WeiXinMPSDK · error · CryptographicException

证书中未包含 RSA 公钥。

Error message

证书中未包含 RSA 公钥。

What it means

SHA256WithRSAVerifier.Verify loads the platform certificate bytes into an X509Certificate2 and calls GetRSAPublicKey(); if the certificate does not contain an RSA public key (e.g. it is an SM2/国密 certificate), a CryptographicException '证书中未包含 RSA 公钥。' is thrown instead of proceeding with RSA signature verification.

Solutions

  1. Set EncryptionType to CertType.SM so TenPayCertFactory wires SM3WithSM2Verifier for 国密 certificates.
  2. Verify you downloaded the standard RSA platform certificate if you intend to use RSA mode.
  3. Check that the certificate bytes passed to Verify belong to the certificate matching the Wechatpay-Serial header.

Example fix

// before
 EncryptionType = CertType.RSA // but cert is SM2
// after
 EncryptionType = CertType.SM // uses SM3WithSM2Verifier
Defensive patterns

Strategy: validation

Validate before calling

using var x509 = new X509Certificate2(certBytes);
if (x509.GetRSAPublicKey() == null)
    throw new InvalidOperationException("Certificate is not RSA; configure EncryptionType = SM instead.");

Type guard

bool IsRsaCertificate(X509Certificate2 c) => c.GetRSAPublicKey() != null;

Try / catch

try { var ok = verifier.Verify(ts, nonce, sig, content, cert, enablePubKey); }
catch (CryptographicException ex) { logger.LogError(ex, "Certificate lacks RSA public key — check CertType"); }

Prevention

When it happens

Trigger: Verifying a WeChat Pay response signature with an RSA verifier while the supplied certificate/public key material is an SM2 (国密) certificate, or the certificate blob is otherwise not RSA-capable.

Common situations: Merchant enrolled in the 国密 pilot but the code path still uses CertType.RSA / SHA256WithRSAVerifier; downloading platform certificates from the SM endpoint; passing the wrong certificate file to the verifier.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12). Data as JSON: /api/errors/d77c539ef754360f. Report an issue: GitHub.

Appendix: source

Thrown at src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/TenPayHttpClient/Verifier/SHA256WithRSAVerifier.cs:70

                    //对比签名
                    byte[] compareByte = sha256.ComputeHash(Encoding.UTF8.GetBytes(contentForSign));
                    //验证签名
                    return df.VerifySignature(compareByte, signature);
                }
            }
            else
            {

                //Base64 解码 pubKey(必须已经使用 ApiSecurityHelper.GetUnwrapCertKey() 方法进行 Unwrap)
                var bs = Convert.FromBase64String(pubKey);
                //使用 X509Certificate2 证书
                using (var x509 = new X509Certificate2(bs))
                using (var key = x509.GetRSAPublicKey())
                using (var sha256 = SHA256.Create())
                {
                    if (key == null)
                    {
                        throw new CryptographicException("证书中未包含 RSA 公钥。");
                    }

                    //RSAPKCS1SignatureDeformatter 对象
                    RSAPKCS1SignatureDeformatter df = new RSAPKCS1SignatureDeformatter(key);
                    //指定 SHA256
                    df.SetHashAlgorithm("SHA256");
                    //应答签名
                    byte[] signature = Convert.FromBase64String(wechatpaySignatureBase64);
                    //对比签名
                    byte[] compareByte = sha256.ComputeHash(Encoding.UTF8.GetBytes(contentForSign));
                    //验证签名
                    return df.VerifySignature(compareByte, signature);
                }
            }
        }
    }
}

View on GitHub (pinned to be573f6f94)