【问题标题】:RSACryptoServiceProvider doesn't produce consistent outputRSACryptoServiceProvider 不会产生一致的输出
【发布时间】:2011-12-17 06:04:39
【问题描述】:

我需要用 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();

我猜这个类一定是在使用其他东西以及影响输出的关键,但我正在努力找出是什么。

【问题讨论】:

  • 解密数据时,每次得到的结果都是一样的吗?
  • 好吧,我以为我没有。这就是为什么我把它全部带回去查看加密的文本,看看它是一样的。但是在我更新答案之前我无法重现这个问题——我想我在 Encrypt() 的第二个参数中混合了填充类型。

标签: c# encryption cryptography padding rsacryptoserviceprovider


【解决方案1】:

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

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

我建议你取这个 b64 文本的任何个实例,将它提交到相反的过程,并看到生成的“rgb”在所有情况下都是“Hello world”。

【讨论】:

    【解决方案2】:

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

    现在这不是您应该使用 RSA 的方式。许多原因,但对您来说最直接的原因是填充/块大小限制了您可以加密的字节数(并且 RSA 太慢,无法考虑循环加密块)。

    我就该主题写了一个blog entry,描述了如何将对称(更快的速度,没有大小限制)与非对称加密相结合 - 两全其美:-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-21
      • 2020-12-26
      • 2017-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多