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

标签 .net cryptography rsa rsacryptoserviceprovider pkcs#1

直到今天,我一直认为使用 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/

相关文章:

c# - .net 分割奇数和偶数管道分隔数据的方法

.net - 为 .NET 跨平台开发组织 Visual Studio 项目和代码的行业标准方法是什么

.net-2.0 - 使用 RSA 公钥解密数据

c - OpenSSL RSA : Unable to encrypt/decrypt messages longer than 16 bytes

Javascript读取私钥信息

c# - 有没有任何工具可以帮助我们将 IEnumerator 属性重构为 IList<T> 或类似的?

c# - 通过 HttpClient 发布文件时 HttpRequest.Files 为空

ssl - Golang 证书验证

python-3.x - 单 key 加密,多 key 解密

PHP shell_exec 使用 ssh 运行 shell 脚本