2011-10-28 117 views
2

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

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(); 

我猜这个类必须使用别的东西,以及关键影响输出,但我在努力寻找什么。

+0

当你对数据进行解密,你每次都得到相同的结果? – robert

+0

嗯,我以为我没有。这就是为什么我把它全部回来看看加密文本,看看它是一样的。但是在我更新我的答案之前,我无法重现问题 - 我想我在第二个参数Encrypt()中混合了填充类型。 – gordonmleigh

回答

1

每次对同一个明文进行加密时,密文的不同并不意味着它不能一致解密。
这确实是一个很好的加密算法的标志,它能够产生这种行为,使其对各种攻击更有弹性。

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

我建议你把任何这个b64文本的实例提交给反向进程,并看到在所有情况下产生的“rgb”是“Hello world”。

1

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

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

我在描述如何可以混合对称的(更好的速度,没有大小限制)与非对称加密的主题写了一blog entry - 获得两全其美的:-)