RSA加解密异常:公钥加密后私钥解密提示‘Key does not exist’求助
解决RSA解密时"Key does not exist"错误
从你的描述和代码片段来看,这个错误几乎都是因为解密时RSA实例没有正确加载私钥或者密钥格式有问题导致的,下面我分点帮你排查和解决:
1. 核心问题:解密时未正确导入私钥
你加密时用了客户端的公钥,但解密时如果只是新建一个RSACryptoServiceProvider(2048)实例,这个实例默认是没有绑定任何私钥的——这就是"Key does not exist"的最常见原因。
解决办法:
解密前必须显式导入你自己的完整私钥,不要依赖默认的空实例。比如用FromXmlString方法加载私钥的XML格式内容:
public string Decrypt(string encryptedText, string myPrivateKeyXml) { byte[] encryptedData = Convert.FromBase64String(encryptedText); using (var rsa = new RSACryptoServiceProvider(2048)) { try { // 关键:导入你的完整私钥XML rsa.FromXmlString(myPrivateKeyXml); // 注意填充模式要和加密时保持一致(这里用PKCS#1,和加密对应) byte[] decryptedData = rsa.Decrypt(encryptedData, false); return Encoding.UTF8.GetString(decryptedData); } finally { // 避免密钥被持久化到容器,防止泄漏 rsa.PersistKeyInCsp = false; } } }
2. 检查密钥格式是否正确
从你的加密代码片段看,你手动拼接了公钥的XML标签,这很容易出错。不管是公钥还是私钥,都应该使用完整的RSA XML格式:
- 公钥XML应该包含:
<RSAKeyValue><Modulus>...</Modulus><Exponent>...</Exponent></RSAKeyValue> - 私钥XML必须包含完整的私钥字段:
Modulus、Exponent、P、Q、DP、DQ、InverseQ、D
如果你的私钥是其他格式(比如PEM),需要先转换成标准的RSA XML格式再导入,否则加载时会失败。
3. 确保加密和解密的填充模式一致
加密和解密必须使用相同的填充模式(比如false对应PKCS#1,true对应OAEP)。如果两边模式不匹配,不仅解密失败,也可能触发密钥相关的错误提示。
修正后的完整加密示例
顺便给你修正下加密代码,避免手动拼接XML的错误:
public string Encrypt(string plainText, string clientPublicKeyXml) { byte[] data = Encoding.UTF8.GetBytes(plainText); using (var rsa = new RSACryptoServiceProvider(2048)) { try { // 直接导入完整的客户端公钥XML,不用手动拼接标签 rsa.FromXmlString(clientPublicKeyXml); // 填充模式和解密保持一致 byte[] encryptedData = rsa.Encrypt(data, false); return Convert.ToBase64String(encryptedData); } finally { rsa.PersistKeyInCsp = false; } } }
内容的提问来源于stack exchange,提问作者Vivek Jeeva Kumar




