导入公钥到RSACryptoServiceProvider报CryptographicException Bad Key如何解决?
问题排查与解决方案
错误根源
- 你调用
RSAPKCS1SignatureDeformatter.VerifySignature时传入了原始的paymentToken字节,这个方法要求传入的是已经哈希运算后的结果,不是原始明文,类型不匹配触发了Bad Key异常 - 调试时看到的
rsa1.CspKeyContainerInfo提示密钥不存在是正常现象:你导入的是公钥,本来就不会存储在CSP密钥容器中,不是问题的诱因
修复方案
可以直接使用RSA类自带的VerifyData方法,它会自动完成哈希运算、签名校验的全流程,不需要手动处理Deformatter,兼容性也更好,修复后代码如下:
private static bool VerifyData(string paymentToken, string signature) { // 优先用RSA.Create替代RSACryptoServiceProvider,兼容性更强,避免CSP相关的平台问题 using var rsa = RSA.Create(); string publicKey = @" <RSAKeyValue><Modulus>zIU140G9rFe6ouNFuhCxIj3Ps3ELUV9w4XTnDsti8kcSTXMf0z6LMNVIqXaZYFbSYXAZRmuM3XNmoSWmMZzPBMl2/C7uC0wyNdrYdPw0uzU2wfr8MQbnvW0yQgQ/cSHNDUZR+n/s2ipXTdNmbRd4z+k+qXxw00xMDmiJu5iMHyYo24x284lTZ3+4dgL4xFlrtjgcb/NGHBpVPQTCbBfEQcmylCwzbTUdBJlAo5ezpziOJ6CNf9FDS1hvRKRvNl7Hx8To6vQZJTwdCT5RWDC2JYL0oSdPV+SZmlfHQQe33p81MiRl4cjp5AwMVKyAosDihGT810WFYhK431EIB/NR/w==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"; rsa.FromXmlString(publicKey); var paymentTokenAsBytes = Encoding.UTF8.GetBytes(paymentToken); var signatureAsBytes = Convert.FromBase64String(signature); try { // 直接调用VerifyData方法,自动处理哈希和校验 bool verified = rsa.VerifyData( data: paymentTokenAsBytes, signature: signatureAsBytes, hashAlgorithm: HashAlgorithmName.SHA256, padding: RSASignaturePadding.Pkcs1); Console.WriteLine(verified ? "签名有效" : "签名无效"); return verified; } catch(CryptographicException ex) { Debug.WriteLine($"校验出错:{ex} "); return false; } }
额外注意点
- 如果坚持要用
RSAPKCS1SignatureDeformatter方案,需要先对原始数据做SHA256哈希,把哈希结果传入VerifySignature方法,不能直接传原始数据 - .NET Core/.NET 5+环境下优先使用
RSA.Create而非RSACryptoServiceProvider,避免Windows平台特有的CSP接口限制导致的莫名错误
内容的提问来源于stack exchange,提问作者Dylan
相关产品推荐
相关产品推荐

