直到今天,我一直认为使用 RSA 的 RSA 加密是确定性的。毕竟,如果不是,签名验证应该如何工作?
令我大吃一惊的是,.NET RSACryptoServiceProvider
使用相同的 key 加密相同的一组字节时,没有稳定的输出:
[Fact]
public void Learning()
{
const int keySize = 1024;
System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Security.Cryptography.RSACryptoServiceProvider(keySize);
var bytes = GenerateRandomDataWithLength( 36 );
for (int i = 0; i < 4; i++)
Assert.Equal( rsa.Encrypt( bytes, false ), rsa.Encrypt( bytes, false ) );
}
byte[] GenerateRandomDataWithLength( int length )
{
Random r = new Random();
byte[] data = new byte[length];
r.NextBytes( data );
return data;
}
我浏览了 PKCS Specification而且我确实了解 RSA 背后的数学原理,所以我真的很想知道为什么我观察到的输出不稳定。
Mono 的 RSA 实现具有稳定的输出。
Encrypt
的不稳定输出不影响解密,这很有可能并产生预期的数据。
最佳答案
RSA 加密是纯数学的,因此每次都会给您相同的结果。然而打电话Encrypt
在 .NET 中不仅仅是做 RSA 加密。
为什么 ? PKCS#1 填充(在 false
中使用 Encrypt
时的默认值)将使每个加密结果都不同,因为它包含随机数据(用于填充目的)。
Mono 有 同 行为(至少在我的系统上,请参阅注释)。但是,如果您使用的是 EncryptValue
,Mono 支持但 .NET 不支持(CryptoAPI 限制),然后 否 将完成填充并且每次加密的结果都相同。
注:如果您有不同的结果,请在 http://bugzilla.xamarin.com 上填写错误报告并包括您正在使用的版本号。
关于.net - 为什么 RSACryptoServiceProvider.Encrypt() 输出不稳定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8310847/