解码 OAEP 填充时出现 RSACryptoServiceProvider 错误
RSACryptoServiceProvider error occurred while decoding OAEP padding
我已经阅读了很多关于这个问题的文章,但我似乎找不到解决我的错误的答案。
我有一个 WCF 服务;我的应用程序发送生成的 public RSA 密钥和服务 returns 一组使用 public 密钥加密的 AES 密钥 + IV,但是当我的应用程序随后尝试解密密钥时,我要么获取 "Error occurred while decoding OAEP padding"(如果我将 true 传递给 useOAEP)或 "The parameter is incorrect"(如果我将 false 传递给 useOAEP)。为简单起见,这是使用的全部代码,将异常处理放在一边:
public static string EncryptAES(byte[] aesKey, byte[] aesIV, string publicRSAKey)
{
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(publicRSAKey);
byte[] encryptedKey = rsa.Encrypt(aesKey, true);
byte[] encryptedIV = rsa.Encrypt(aesIV, true);
return string.Format("{0}{1}{2}", Convert.ToBase64String(encryptedKey), "\n", Convert.ToBase64String(encryptedIV));
}
}
public static byte[] Decrypt(string aesKeyorIV)
{
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
byte[] buffer = Convert.FromBase64String(aesKeyorIV);
rsa.FromXmlString(RSA_Private_Key);
return rsa.Decrypt(buffer, true); //Exception thrown here
}
}
(RSA_Private_Key
是在静态构造函数中使用rsa.ToXmlString(true)
生成的)
(publicRSAKey
通过在静态构造函数中发送 rsa.ToXmlString(false)
传递给服务)
我尝试使用 Encrypt/Decrypt(byte[], false)
但它没有任何区别。我也尝试了 Array.Reverse(encryptedKey)
然后 Array.Reverse(buffer)
。
私钥在设置后永远不会 sent/modified 所以不可能。
我没有想法,调试 WCF 服务非常糟糕。
您描述的问题可能是由于使用了与 Public 密钥不同的私钥造成的。
如果您使用 RSA 提供程序的相同实例生成 public 和 public+私钥,则密钥将匹配。例如
string publicRSAKey = null;
string publicPlusPrivateRSAKey = null;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
publicRSAKey = rsa.ToXmlString(false);
publicPlusPrivateRSAKey = rsa.ToXmlString(true);
}
如果您从 RSA 提供商的两个不同实例创建密钥,则 public 和 public+私钥将不匹配。例如
string publicRSAKey = null;
string publicPlusPrivateRSAKey = null;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
publicRSAKey = rsa.ToXmlString(false);
}
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
publicPlusPrivateRSAKey = rsa.ToXmlString(true);
}
当密钥匹配时,我可以毫无问题地往返。当键不匹配时,我得到 "Error occured while decoding OAEP padding.".
你能验证密钥在运行时是否匹配吗?
由于私钥也将包含 Public 密钥,您可以查看 xml 字符串形式的每个密钥变量的内容,特别是 XML 路径 /RSAKeyValue/Modulus 和 /RSAKeyValue/Exponent,因为它们应该在两者之间匹配。
我终于找到bug了。我的实施如下,经过简化:
- 应用程序创建 public+私钥并将 public 密钥发送到服务
- 该服务使用 AES 生成的密钥进行响应,该密钥使用 public 密钥加密。
- 服务随后尝试解密密钥,然后引发事件以提醒应用程序。
我更改了我的实现,例如:
- 服务使用加密消息引发事件
- 应用程序使用私钥解密消息。
因为我使用一个 Visual Studio 实例来调试 2 个进程(服务的和 visual studio 调试器的),所以我没有意识到 private/public 键是不同的。
感谢@zespri 提供测试思路。
我已经阅读了很多关于这个问题的文章,但我似乎找不到解决我的错误的答案。
我有一个 WCF 服务;我的应用程序发送生成的 public RSA 密钥和服务 returns 一组使用 public 密钥加密的 AES 密钥 + IV,但是当我的应用程序随后尝试解密密钥时,我要么获取 "Error occurred while decoding OAEP padding"(如果我将 true 传递给 useOAEP)或 "The parameter is incorrect"(如果我将 false 传递给 useOAEP)。为简单起见,这是使用的全部代码,将异常处理放在一边:
public static string EncryptAES(byte[] aesKey, byte[] aesIV, string publicRSAKey)
{
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(publicRSAKey);
byte[] encryptedKey = rsa.Encrypt(aesKey, true);
byte[] encryptedIV = rsa.Encrypt(aesIV, true);
return string.Format("{0}{1}{2}", Convert.ToBase64String(encryptedKey), "\n", Convert.ToBase64String(encryptedIV));
}
}
public static byte[] Decrypt(string aesKeyorIV)
{
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
byte[] buffer = Convert.FromBase64String(aesKeyorIV);
rsa.FromXmlString(RSA_Private_Key);
return rsa.Decrypt(buffer, true); //Exception thrown here
}
}
(RSA_Private_Key
是在静态构造函数中使用rsa.ToXmlString(true)
生成的)
(publicRSAKey
通过在静态构造函数中发送 rsa.ToXmlString(false)
传递给服务)
我尝试使用 Encrypt/Decrypt(byte[], false)
但它没有任何区别。我也尝试了 Array.Reverse(encryptedKey)
然后 Array.Reverse(buffer)
。
私钥在设置后永远不会 sent/modified 所以不可能。
我没有想法,调试 WCF 服务非常糟糕。
您描述的问题可能是由于使用了与 Public 密钥不同的私钥造成的。
如果您使用 RSA 提供程序的相同实例生成 public 和 public+私钥,则密钥将匹配。例如
string publicRSAKey = null;
string publicPlusPrivateRSAKey = null;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
publicRSAKey = rsa.ToXmlString(false);
publicPlusPrivateRSAKey = rsa.ToXmlString(true);
}
如果您从 RSA 提供商的两个不同实例创建密钥,则 public 和 public+私钥将不匹配。例如
string publicRSAKey = null;
string publicPlusPrivateRSAKey = null;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
publicRSAKey = rsa.ToXmlString(false);
}
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
publicPlusPrivateRSAKey = rsa.ToXmlString(true);
}
当密钥匹配时,我可以毫无问题地往返。当键不匹配时,我得到 "Error occured while decoding OAEP padding.".
你能验证密钥在运行时是否匹配吗?
由于私钥也将包含 Public 密钥,您可以查看 xml 字符串形式的每个密钥变量的内容,特别是 XML 路径 /RSAKeyValue/Modulus 和 /RSAKeyValue/Exponent,因为它们应该在两者之间匹配。
我终于找到bug了。我的实施如下,经过简化:
- 应用程序创建 public+私钥并将 public 密钥发送到服务
- 该服务使用 AES 生成的密钥进行响应,该密钥使用 public 密钥加密。
- 服务随后尝试解密密钥,然后引发事件以提醒应用程序。
我更改了我的实现,例如:
- 服务使用加密消息引发事件
- 应用程序使用私钥解密消息。
因为我使用一个 Visual Studio 实例来调试 2 个进程(服务的和 visual studio 调试器的),所以我没有意识到 private/public 键是不同的。
感谢@zespri 提供测试思路。