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
- Set EncryptionType to CertType.SM so TenPayCertFactory wires SM3WithSM2Verifier for 国密 certificates.
- Verify you downloaded the standard RSA platform certificate if you intend to use RSA mode.
- 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
- Match CertType to the certificate family actually issued by WeChat Pay (RSA vs SM2).
- Inspect downloaded platform certificates (thumbprint/key algorithm) before wiring them into the verifier.
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
- 证书中未包含 RSA 公钥。
- 证书中未包含 RSA 公钥。
- 品牌 API 通知的微信支付公钥 ID 与配置不匹配。
- RequestAsync 签名验证失败:
- WeixinPayInfoCollection尚未注册Partner:
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)