RSACryptoServiceProvider不会生成一致的输出

时间:2011-10-28 11:57:59

标签: c# encryption cryptography padding rsacryptoserviceprovider

我需要使用RSA加密某些文本,然后使用私钥恢复它。我的问题是RSACryptoServiceProvider.Encrypt()每次输出一个不同的值,即使使用相同的密钥。这是我在LINQpad中测试的代码:

CspParameters cp = new CspParameters();
cp.KeyContainerName = "MyKey";
cp.Flags = CspProviderFlags.UseMachineKeyStore | CspProviderFlags.UseExistingKey;

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);

// using LINQpad to verify the key is loaded properly -- same every time
rsa.ToXmlString(true).Dump();

byte[] rgb = new ASCIIEncoding().GetBytes("Hello world");
byte[] xx = rsa.Encrypt(rgb, false);
string b64 = Convert.ToBase64String(xx);

// this changes every time:
b64.Dump();

我猜这个班级必须使用其他东西以及影响输出的关键,但我很难找到答案。

2 个答案:

答案 0 :(得分:1)

每次加密相同的明文时密码文本不同这一事实并不意味着它无法一致地解密。
这确实是一个良好的加密算法的标志,能够有这种行为,使其更能适应各种攻击。

这是因为加密逻辑在过程中引入了随机性,例如通过在明文本身之前系统地添加一些随机字节。只要解密逻辑知道在整个密文被解密后忽略这些字节,那么它就可以重现原始的明文。

我建议您使用此b64文本的任何实例,将其提交给相反的过程,并查看所有情况下生成的“rgb”是“Hello world”。

答案 1 :(得分:1)

不同的输出完全正常。这是因为您的数据被PKCS#1或OAEP填充 - 并且两者都在使用/添加一些随机数据。

现在这不是你应该如何使用RSA。很多原因,但对你来说最直接的原因是因为填充/块大小限制了你可以加密的字节数(并且RSA太慢而不能考虑循环加密块)。

我在这个主题上写了blog entry,描述了如何将对称(更好的速度,没有大小限制)与非对称加密混合在一起 - 充分利用两个世界: - )