C#中的大数据RSA加密

这是我的第一篇文章,所以希望我没有错过任何重要的内容。 我在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来简化它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文档中消除错误的解析错误…

当我运行测试客户端时,如果我使用私钥加密和公钥解密,我得到一个“密钥不存在exception”,如果我反过来这样做,我得到一个错误的数据exception。

请帮帮我们,如果你知道任何好的指南,或者可以告诉我如何对字符串消息实施公钥/私钥加密,请帮帮我。

我感谢任何帮助。

这不是RSA加密应该如何完成的。

RSA是关于数学的。 您加密的是一个数字,因此它必须是有限长度并且与您正在使用的RSA密钥对长度相匹配。 使用的填充(PKCS#1或OAEP)会进一步限制长度。

如果要使用RSA加密大型数据,则需要间接进行 – 即使用对称密钥加密大数据并使用RSA公钥加密此密钥。

您可以在我的博客上阅读有关实施此内容

好的,我终于想出了解决我在原帖中所说的问题的方法。 这是我没有经过彻底测试或其他任何东西,但我从一个小试验和错误过程中找到的东西。

这是我目前的代码:

  public static string Encrypt(string dataToEncrypt, RSAParameters publicKeyInfo) { //// Our bytearray to hold all of our data after the encryption byte[] encryptedBytes = new byte[0]; using (var RSA = new RSACryptoServiceProvider()) { try { //Create a new instance of RSACryptoServiceProvider. UTF8Encoding encoder = new UTF8Encoding(); byte[] encryptThis = encoder.GetBytes(dataToEncrypt); //// Importing the public key RSA.ImportParameters(publicKeyInfo); int blockSize = (RSA.KeySize / 8) - 32; //// buffer to write byte sequence of the given block_size byte[] buffer = new byte[blockSize]; byte[] encryptedBuffer = new byte[blockSize]; //// Initializing our encryptedBytes array to a suitable size, depending on the size of data to be encrypted encryptedBytes = new byte[encryptThis.Length + blockSize - (encryptThis.Length % blockSize) + 32]; for (int i = 0; i < encryptThis.Length; i += blockSize) { //// If there is extra info to be parsed, but not enough to fill out a complete bytearray, fit array for last bit of data if (2 * i > encryptThis.Length && ((encryptThis.Length - i) % blockSize != 0)) { buffer = new byte[encryptThis.Length - i]; blockSize = encryptThis.Length - i; } //// If the amount of bytes we need to decrypt isn't enough to fill out a block, only decrypt part of it if (encryptThis.Length < blockSize) { buffer = new byte[encryptThis.Length]; blockSize = encryptThis.Length; } //// encrypt the specified size of data, then add to final array. Buffer.BlockCopy(encryptThis, i, buffer, 0, blockSize); encryptedBuffer = RSA.Encrypt(buffer, false); encryptedBuffer.CopyTo(encryptedBytes, i); } } catch (CryptographicException e) { Console.Write(e); } finally { //// Clear the RSA key container, deleting generated keys. RSA.PersistKeyInCsp = false; } } //// Convert the byteArray using Base64 and returns as an encrypted string return Convert.ToBase64String(encryptedBytes); } ///  /// Decrypt this message using this key ///  ///  /// The data To decrypt. ///  ///  /// The private Key Info. ///  ///  /// The decrypted data. ///  public static string Decrypt(string dataToDecrypt, RSAParameters privateKeyInfo) { //// The bytearray to hold all of our data after decryption byte[] decryptedBytes; //Create a new instance of RSACryptoServiceProvider. using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider()) { try { byte[] bytesToDecrypt = Convert.FromBase64String(dataToDecrypt); //// Import the private key info RSA.ImportParameters(privateKeyInfo); //// No need to subtract padding size when decrypting (OR do I?) int blockSize = RSA.KeySize / 8; //// buffer to write byte sequence of the given block_size byte[] buffer = new byte[blockSize]; //// buffer containing decrypted information byte[] decryptedBuffer = new byte[blockSize]; //// Initializes our array to make sure it can hold at least the amount needed to decrypt. decryptedBytes = new byte[dataToDecrypt.Length]; for (int i = 0; i < bytesToDecrypt.Length; i += blockSize) { if (2 * i > bytesToDecrypt.Length && ((bytesToDecrypt.Length - i) % blockSize != 0)) { buffer = new byte[bytesToDecrypt.Length - i]; blockSize = bytesToDecrypt.Length - i; } //// If the amount of bytes we need to decrypt isn't enough to fill out a block, only decrypt part of it if (bytesToDecrypt.Length < blockSize) { buffer = new byte[bytesToDecrypt.Length]; blockSize = bytesToDecrypt.Length; } Buffer.BlockCopy(bytesToDecrypt, i, buffer, 0, blockSize); decryptedBuffer = RSA.Decrypt(buffer, false); decryptedBuffer.CopyTo(decryptedBytes, i); } } finally { //// Clear the RSA key container, deleting generated keys. RSA.PersistKeyInCsp = false; } } //// We encode each byte with UTF8 and then write to a string while trimming off the extra empty data created by the overhead. var encoder = new UTF8Encoding(); return encoder.GetString(decryptedBytes).TrimEnd(new[] { '\0' }); } 

正如我所说的那样,除了大小以外,我还没有对块大小进行过多次测试,但它似乎正在做它应该做的事情。 我仍然是新手,所以我真的希望你仔细检查我的代码:)

也许我错过了一些东西,但看起来你的Encrypt()函数没有使用keyString参数或encryptKey的内容。