.net 为什么RSACryptServiceProvider.Encrypt()输出不稳定?

.net 为什么RSACryptServiceProvider.Encrypt()输出不稳定?,.net,cryptography,rsa,rsacryptoserviceprovider,pkcs#1,.net,Cryptography,Rsa,Rsacryptoserviceprovider,Pkcs#1,直到今天,我一直认为使用RSA的RSA加密是确定性的。毕竟,如果不是,签名验证应该如何工作 令我大吃一惊的是,.NETsrsacyptoserviceprovider在使用相同密钥加密同一组字节时没有稳定的输出: [Fact] public void Learning() { const int keySize = 1024; System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Secur

直到今天,我一直认为使用RSA的RSA加密是确定性的。毕竟,如果不是,签名验证应该如何工作

令我大吃一惊的是,.NETs
rsacyptoserviceprovider
在使用相同密钥加密同一组字节时没有稳定的输出:

[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;
}
[事实]
公共学习()
{
const int keySize=1024;
System.Security.Cryptography.RSACryptoServiceProvider rsa=新的System.Security.Cryptography.RSACryptoServiceProvider(密钥大小);
var bytes=GenerateRandomDataWithLength(36);
对于(int i=0;i<4;i++)
Assert.Equal(rsa.Encrypt(bytes,false),rsa.Encrypt(bytes,false));
}
字节[]GeneratorDomainDataWithLength(int-length)
{
随机r=新随机();
字节[]数据=新字节[长度];
r、 下字节(数据);
返回数据;
}
我浏览了一下,我确实理解RSA背后的数学原理,所以我真的想知道为什么我观察到输出是不稳定的


Mono的RSA实现具有稳定的输出。
Encrypt
的不稳定输出不会影响解密,这很可能会产生预期的数据

RSA加密是纯数学的,因此每次都会得到相同的结果。然而,在.NET中调用
Encrypt
并不仅仅是执行RSA加密

为什么?PKCS#1填充(在
加密
中使用
false
时默认)将使每个加密结果都不同,因为它包含随机数据(用于填充目的)

Mono具有相同的行为(至少在我的系统上,请参见注释)。但是,如果您使用的是Mono支持但.NET不支持的
EncryptValue
(CryptoAPI限制),则将执行填充,并且每次加密的结果都相同


注意:如果您有不同的结果,请填写错误报告并包含您正在使用的版本号。

好的,我完全忘记了填充随机数据。你显然就在这里。谢谢你的回答!(我提到的mono版本非常古老,实际上它只是Monos RSA的源代码)。@Johannes注意到,需要一些随机填充,以使RSA加密能够抵御选定的明文攻击(即再次加密猜测的明文,以查看输出是否与之前截获的匹配)为了清楚起见,我想补充一点,在
加密
中使用
true
也会导致随机填充,我相信(
OAEP
)。