【问题标题】:Asymetric encryption algorithm which allows to use public and private key for both encryption and decryption非对称加密算法,允许使用公钥和私钥进行加密和解密
【发布时间】:2019-12-29 16:11:50
【问题描述】:

我有以下工作的非对称加密实现:

private static RSAParameters privateKey;
private static RSAParameters publicKey;

private static void RSA()
{
  var rsa = new RSACryptoServiceProvider();
  privateKey = rsa.ExportParameters(true);
  publicKey = rsa.ExportParameters(false);

  byte[] originalMessage = GenerateRandomData();
  byte[] encryptedMessage = Using(publicKey).Encrypt(originalMessage, false);
  byte[] decryptedMessage = Using(privateKey).Decrypt(encryptedMessage, false);
  Debug.Assert(originalMessage.SequenceEqual(decryptedMessage));
}

private static RSACryptoServiceProvider Using(RSAParameters parameters)
{
  RSACryptoServiceProvider encryptor = new RSACryptoServiceProvider();
  encryptor.ImportParameters(parameters);
  return encryptor;
}

private static byte[] GenerateRandomData()
{
  Random rnd = new Random();
  byte[] originalData = new byte[10];
  rnd.NextBytes(originalData);
  return originalData;
}

我用它用接收者的公钥 [Using(publicKey).Encrypt(originalData)] 加密数据,这样接收者就只能解密数据 [Using(privateKey).Decrypt(encryptedData)]。

现在我想为以下用例重用非对称加密:接收者发布数据以及知道接收者公钥的每个人(基本上是系统中的每个人,但系统外没有人,例如防止将可读数据泄露给公众)可以阅读。发布者使用他的私钥进行加密,而他的公钥将用于解密:

byte[] originalData = GenerateRandomData();
byte[] publishedData = Using(privateKey).Encrypt(originalData, false);
byte[] retrievedData = Using(publicKey).Decrypt(publishedData, false);
Debug.Assert(originalData.SequenceEqual(retrievedData));

然而这会产生一个

System.Security.Cryptography.CryptographicException
  HResult=0x8009000D
  Message=Keyset does not exist.

我不想为数据发布部分使用不同的公钥-私钥对,尤其是在这种情况下,这意味着将公钥设为私钥。打字的时候已经很尴尬了……

编辑:.NET 框架中是否包含非对称加密,它允许我在两个方向上使用两个密钥(公共和私有),如果一个密钥用于加密,则只有另一个可以用于解密?

【问题讨论】:

  • RSA 签名不是解密。对于加密,您应该使用适当的填充作为 PKCS#1.5 或 OAEP。对于签名,您应该使用 RSA-PSS。通常我们不建议使用 RSA 加密消息,消息空间会很短,您可能需要多次加密,这会使您的应用程序非常慢。 RSA 可用于像 RSA-KEM 一样的密钥交换。之后,您可以使用 AES 进行加密。实际上,如果你能找到 C# 库,sealed boxes 就是一个不错的库。
  • Bouncycastle C# 库有一个 RSAEngine 类,可让您执行此操作。
  • 不要试图使用私钥作为您发布的“公钥”,并保持公钥“秘密”。在实践中给定一个私钥,从中派生公钥是微不足道的。
  • @JimFlood 打字时听起来已经很尴尬了。我保证我不会。但感谢您确认并指出这一点。

标签: c# encryption public-key-encryption public-key


【解决方案1】:

RSA 签名与使用私钥加密不同。

PKCS#1 v1.5 签名:

  • 使用选定的算法对内容进行散列。
  • 创建一个 DigestInfo 值来表示哈希。
  • 应用填充使消息几乎但不完全是模数的大小(此处省略详细信息)。
  • 将 RSA 原语与私钥一起应用

请注意,最后一步没有说“加密”。

.NET 中的 RSA 类为您执行填充等操作,因此它们公开了签名/验证和加密/解密。您不能将它们用于交叉用途,也不能将这些类用于 RSA 原语(也称为“原始 RSA”)。

【讨论】:

  • 我没有尝试执行签名(即使我在问题中使用了该术语)。我更改了标题以使我的问题更清楚。但是我已经从你的回答中假设没有这样的不对称算法。
  • @David 你说得对,答案是“不”。公就是公,私就是私。加密使用公共。来源证明通过散列提供,即私钥和散列。
  • 我是否也正确,相反“学术” RSA 算法允许它?
  • @David 原语的关系(m^k % n,其中 k 是公共指数或私人指数;并且再次“撤消”另一个)允许它。但是 RSA 作为一种算法在实践中需要更多的结构来保证安全(security.stackexchange.com/questions/183179/… 是该语句的更长版本)
猜你喜欢
  • 2015-01-25
  • 1970-01-01
  • 2023-03-24
  • 2017-11-25
  • 2012-04-11
  • 1970-01-01
  • 1970-01-01
  • 2017-01-12
  • 2014-07-12
相关资源
最近更新 更多