Detailed explanation of C RSA segmented encryption and decryption implementation method

  • 2021-12-11 18:43:17
  • OfStack

In this paper, the implementation method of C # RSA segmented encryption and decryption is described by examples. Share it for your reference, as follows:

RSA encryption and decryption:

A 1024-bit certificate supports a maximum of 117 bytes when encrypted and 128 when decrypted;

A 2048-bit certificate supports a maximum of 245 bytes when encrypted and 256 bytes when decrypted.

Maximum number of bytes supported for encryption: certificate digital/8-11 (for example: 2048-bit certificate, maximum number of encrypted bytes supported: 2048/8-11 = 245)

In order to improve the security, RSA encryption algorithm in NET should add some random numbers before the data to be encrypted. Therefore, RSA encryption algorithm in NET should be used to encrypt 117 bytes of data at most once (more than 117 bytes need to be split into multiple segments to encrypt and then connect), and after encryption, an encrypted data with a length of 128 bytes can be obtained.

The maximum length of plaintext that RSA can actually encrypt is 1024bits, but here comes the question: What if it is less than this length? padding is needed, because without padding, users can't distinguish the true length of decrypted content, and the content such as string is not a big problem, with 0 as the terminator, but it is difficult to understand binary data, because it is uncertain whether the following 0 is content or content terminator. As long as padding is used, it takes up the actual plaintext length, so there is a saying of 117 bytes. We generally use padding standards such as NoPPadding, OAEPPadding, PKCS1Padding, etc. Among them, padding recommended by PKCS # 1 occupies 11 bytes. What if it is greater than this length? The padding of many algorithms is often behind, but the padding of PKCS is in front, which is deliberately designed. The first byte is set to 0 to ensure that the value of m is less than that of n. In this way, 128 bytes (1024bits)-minus 11 bytes is exactly 117 bytes, but for RSA encryption, padding is also involved in encryption, so it is still understood according to 1024bits, but the actual plaintext is only 117 bytes.

C # code implementation:


internal static string GetEncryptedMsg(string xml)
{
  byte[] encryptedData;
  using (var rsa = GetPublicKey(Configs.PublicKeyFilePath))
  {
    var plainData = Encoding.UTF8.GetBytes(xml);
    using (var plaiStream = new MemoryStream(plainData))
    {
      using (var crypStream = new MemoryStream())
      {
        var offSet = 0;
        var inputLen = plainData.Length;
        for (var i = 0; inputLen - offSet > 0; offSet = i*244)
        {
          if (inputLen - offSet > 244)
          {
            var buffer = new Byte[244];
            plaiStream.Read(buffer, 0, 244);
            var cryptograph = rsa.Encrypt(buffer, false);
            crypStream.Write(cryptograph, 0, cryptograph.Length);
          }
          else
          {
            var buffer = new Byte[inputLen - offSet];
            plaiStream.Read(buffer, 0, inputLen - offSet);
            var cryptograph = rsa.Encrypt(buffer, false);
            crypStream.Write(cryptograph, 0, cryptograph.Length);
          }
          ++i;
        }
        crypStream.Position = 0;
        encryptedData = crypStream.ToBytes();
      }
    }
  }
  return BitConverter.ToString(encryptedData).Replace("-", string.Empty);
}
internal static byte[] GetDecryptedMsg(byte[] encryptedBytes)
{
  using (var rsa = GetPrivateKey(Configs.PrivateKeyFilePath, Configs.PrivateKeyPasswd))
  {
    byte[] decryptedData;
    using (var plaiStream = new MemoryStream(encryptedBytes))
    {
      using (var decrypStream = new MemoryStream())
      {
        var offSet = 0;
        var inputLen = encryptedBytes.Length;
        for (var i = 0; inputLen - offSet > 0; offSet = i * 256)
        {
          if (inputLen - offSet > 256)
          {
            var buffer = new Byte[256];
            plaiStream.Read(buffer, 0, 256);
            var decrypData = rsa.Decrypt(buffer, false);
            decrypStream.Write(decrypData, 0, decrypData.Length);
          }
          else
          {
            var buffer = new Byte[inputLen - offSet];
            plaiStream.Read(buffer, 0, inputLen - offSet);
            var decrypData = rsa.Decrypt(buffer, false);
            decrypStream.Write(decrypData, 0, decrypData.Length);
          }
          ++i;
        }
        decrypStream.Position = 0;
        decryptedData = decrypStream.ToBytes();
      }
    }
    return decryptedData;
  }
}

PS: Friends who are interested in encryption and decryption can also refer to the online tools of this site:

MD5 Online Encryption Tool:
http://tools.ofstack.com/password/CreateMD5Password

Thunderbolt, Express, Cyclone URL Encryption/Decryption Tool:
http://tools.ofstack.com/password/urlrethunder

Online hash/hash algorithm encryption tool:
http://tools.ofstack.com/password/hash_encrypt

Online MD5/hash/SHA-1/SHA-2/SHA-256/SHA-512/SHA-3/RIPEMD-160 Encryption Tool:
http://tools.ofstack.com/password/hash_md5_sha

Online sha1/sha224/sha256/sha384/sha512 Encryption Tool:
http://tools.ofstack.com/password/sha_encode

For more information about C #, please see the topic of this site: "C # Encryption and Decryption Algorithms and Skills Summary", "C # Form Operation Skills Summary", "C # Common Control Usage Tutorial", "WinForm Control Usage Summary", "C # Programming Thread Use Skills Summary", "C # Operating Excel Skills Summary", "XML File Operation Skills Summary in C #", "C # Data Structure and Algorithm Tutorial", "C # Array Operation Skills Summary" and "C # Object-Oriented Programming Introduction Tutorial"

I hope this article is helpful to everyone's C # programming.


Related articles: