【发布时间】: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