我想实现一个场景,其中两个端点可以使用公钥/私钥加密安全地相互通信。方案如下:
对于A向B发送消息:
A使用A的私钥加密消息。
A使用B的公钥加密消息。
A发送消息。
B收到消息。
B使用A的公钥解密消息。
B使用B的私钥解密邮件。
B读取消息。
以下是我在C#中使用RSA加密的内容:
// Alice wants to send a message to Bob:
String plainText = "Hello, World!";
Byte[] plainData = Encoding.Default.GetBytes(plainText);
Byte[] cipherData = null;
RSACryptoServiceProvider alice = new RSACryptoServiceProvider();
RSACryptoServiceProvider bob = new RSACryptoServiceProvider();
var alicePrivateKey = alice.ExportParameters(true);
var alicePublicKey = alice.ExportParameters(false);
var bobPrivateKey = bob.ExportParameters(true);
var bobPublicKey = bob.ExportParameters(false);
RSACryptoServiceProvider messenger = new RSACryptoServiceProvider();
messenger.ImportParameters(alicePrivateKey);
cipherData = messenger.Encrypt(plainData, true);
messenger.ImportParameters(bobPublicKey);
cipherData = messenger.Encrypt(cipherData, true);
messenger.ImportParameters(alicePublicKey);
cipherData = messenger.Decrypt(cipherData, true);
messenger.ImportParameters(bobPrivateKey);
cipherData = messenger.Decrypt(cipherData, true);
String result = Encoding.Default.GetString(alice.Decrypt(cipherData, true));
显然,以下几行有问题:
messenger.ImportParameters(bobPublicKey);
cipherData = messenger.Encrypt(cipherData, true);
使用消息 {“Bad Length”} 抛出 System.Security.Cryptography.CryptographyException 。
我可以看到它只能使用bob键的公共部分来加密数据。
有人可以说明如何在 C#中正确完成我想做的事吗?
答案 0 :(得分:4)
这里有两个问题:
A)您的协议设计错误。如果要使用RSA交换消息,则算法为:
使用B的公开键
加密消息A发送消息
B使用B的私有键
对邮件进行解密(B做处理)
B使用A的公开键
加密邮件B发送消息
使用A的私有键
解密邮件等等。注意A如何不知道B的私钥,反之亦然。公钥和私钥以这样的方式相关联:用公钥(每个人都知道)加密的消息只能用相应的私钥解密(只有加密消息的有意接收者知道)。实际上,这是RSA的重点。
至于C#中的实现,一旦你真正理解了底层概念,就可以使用Crypto类。例如,请参阅here和here。
B)RSA适合交换少量数据。它用于通过不安全的通道进行密钥交换,而无需共享密钥。为了交换“正常”数据,使用诸如AES的对称算法。因此,想法是从A生成随机密码和IV,并通过RSA将其发送到B,如A中所讨论的;在双方都知道密码短语和IV后,他们只能使用带有共享密钥的AES加密数据。
SSL就是这样做的,你应该有充分的理由来推广自己而不是使用标准的SSL流。
答案 1 :(得分:1)
RSA用于加密小于密钥的数据。您使用对称密钥加密大量数据,然后使用RSA共享对称密钥。
有关详细信息,请参阅此问题:how to use RSA to encrypt files (huge data) in C#