这是我的第一篇文章,所以希望我没有错过任何重要的事情。我正在C#中做一个项目,我需要使用公用/专用密钥加密来加密消息,然后通过SSL连接发送消息。
RSACryptoService
根据文档,我选择使用,这是用于加密数据的唯一非对称加密方案。问题是我对此有很多问题。(我想做对称加密,但这不是我的老师想要我做的,对他来说,确定一块大小然后应该为你完成所有工作应该很容易。)运气不好,我尝试了一些不同的方法,但是现在我回到基础知识,然后再试一次,这是我当前的代码:
public string[] GenerateKeysToStrings(string uniqueIdentifier)
{
string[] keys;
using (var rsa = new RSACryptoServiceProvider(4096))
{
try
{
string privateKey = rsa.ToXmlString(true);
string publicKey = rsa.ToXmlString(false);
this.pki.StoreKey(publicKey, uniqueIdentifier);
keys = new string[2];
keys[0] = privateKey;
keys[1] = publicKey;
}
finally
{
//// Clear the RSA key container, deleting generated keys.
rsa.PersistKeyInCsp = false;
}
}
return keys;
}
如你所见,我生成了密钥,并通过将公钥发送到存储公钥的简单类来模仿PKI,然后将私钥写入文件中(注意,我还有另一种方法可以做到这一点,但是而是将其存储到数组中,只是因为我想No such key exceptions
按示例中所示的方式测试并简化获取的内容,有时还需要加密异常,因此我想通过简单地将rsa.ToXmlString
字符串存储为字符串来简化它。数组,但没有运气。)
现在,我有一个加密和解密方法,如下所示:
public string Encrypt(string keyString, string message)
{
string encryptedMessage;
using (var rsa = new RSACryptoServiceProvider())
{
try
{
//// Load the key from the specified path
var encryptKey = new XmlDocument();
encryptKey.Load(@"C:\Test\PrivateKeyInfo.xml");
rsa.FromXmlString(encryptKey.OuterXml);
//// Conver the string message to a byte array for encryption
//// var encoder = new UTF8Encoding();
ASCIIEncoding byteConverter = new ASCIIEncoding();
byte[] dataToEncrypt = byteConverter.GetBytes(message);
byte[] encryptedData = rsa.Encrypt(dataToEncrypt, false);
//// Convert the byte array back to a string message
encryptedMessage = byteConverter.GetString(encryptedData);
}
finally
{
//// Clear the RSA key container, deleting generated keys.
rsa.PersistKeyInCsp = false;
}
}
return encryptedMessage;
}
解密:
public string Decrypt(string keyString, string message)
{
string decryptedText;
using (var rsa = new RSACryptoServiceProvider())
{
try
{
//// Loads the keyinfo into the rsa parameters from the keyfile
/*
var privateKey = new XmlDocument();
privateKey.Load(keyString);
*/
rsa.FromXmlString(keyString);
//// Convert the text from string to byte array for decryption
ASCIIEncoding byteConverter = new ASCIIEncoding();
var encryptedBytes = byteConverter.GetBytes(message);
//// Create an aux array to store all the encrypted bytes
byte[] decryptedBytes = rsa.Decrypt(encryptedBytes, false);
decryptedText = byteConverter.GetString(decryptedBytes);
}
finally
{
//// Clear the RSA key container, deleting generated keys.
rsa.PersistKeyInCsp = false;
}
}
return decryptedText;
}
我知道这是一堵文字墙,但是我希望你能为我提供帮助,因为我已经将头撞墙了很长时间了,这并不好笑:)
问题是,我该如何使用RSA
(或其他任何公/私钥加密)加密消息
这是测试客户端:
public static void Main(string[] args)
{
PublicKeyInfrastructure pki = new PublicKeyInfrastructure();
Cryptograph crypto = new Cryptograph();
string[] keys = crypto.GenerateKeysToStrings("simonlanghoff@gmail.com");
string plainText = "Hello play with me, please";
string publicKey = crypto.GetPublicKey("simonlanghoff@gmail.com");
string encryptedText = crypto.Encrypt(keys[0], plainText);
string decryptedText = crypto.Decrypt(keys[1], encryptedText);
}
如前所述,字符串数组之所以存在,是因为我想消除XML文档中的错误解析错误...
当运行测试客户端时,如果我使用私钥进行加密,而使用公钥进行解密,则会得到“密钥不存在异常”,如果反之,则会得到错误的数据异常。
请大家帮帮我,如果你知道任何好的指南,或者可以告诉我如何对字符串消息进行一些直截了当的公共/私有密钥加密,请帮助我。
感谢你的帮助。
这不是应该执行RSA加密的方式。
RSA与数学有关。你加密的是一个数字,因此它必须是有限的长度,并且必须与你使用的RSA密钥对长度匹配。所使用的填充(PKCS#1或OAEP)会进一步限制长度。
如果要使用RSA加密大数据,则需要间接进行-即使用对称密钥来加密大数据,并使用RSA公钥对该密钥进行加密。
你可以在我的博客上阅读有关实现此方法的信息。
我与教授交谈,当时我的观点是,最好加密密钥,交换密钥,然后将其用作对称算法的基础,例如rijndael来加密/解密消息,但是,他不希望我们使用对称加密,所以现在我处于那种有点超限的位置。在性能方面,当我们谈论包含用户名和密码的HTTP消息时,一次加密消息需要花费多少时间,一次需要501字节(使用4096位RSA密钥)?是否逐块编码,实际上使用RSA还是有问题:(
您可以循环RSA加密/解密以使其保持在大小限制(包括填充)之内,并连接/分割结果。多少时间 ?这取决于您的CPU,是否是旧的智能手机和新的8核服务器?;-),但比正确的选择要长得多。
我希望可以计时,但是现在我什至无法使它适用于任何数据。我使用了一个简化的版本,并使用了它,但是,我仍然收到“键不存在”错误,而我真正所做的只是重构设计,从单个主要方法到单独的方法。也许我正在使用构造函数,对吗?我要导入密钥设置的部分?我知道,分组密码比对称算法慢1000倍,但现在我只想让它起作用,无论是否必须对其进行硬编码,以便将每个数据块都切成(keysize / 8- 11(用于填充))字节。
查看您的代码。您的
Encrypt
方法不使用keyString
参数,而是加载XML文件(带有密钥?),但对其内容不执行任何操作。看起来您正在使用自动生成的密钥(默认值为1024位)进行加密,因此该密钥与解密不匹配。我想我已经找到了获取密钥不存在错误的原因,并且每次我使用私钥加密数据时都会发生这种情况。我以为您使用什么密钥都没关系,请,如果我在此问题上做错了,请更正我,但是我猜想,由于私钥加密用于验证而不是保守秘密,因此加密和加密都可以。 RSA CryptoService提供程序的解密方法不允许您使用私钥,而应仅用于签名/验证。但这不能解释为什么我会收到带有公共密钥的错误数据异常?