简体   繁体   English

RSA 加密,长度变差

[英]RSA Encryption, getting bad length

When calling the following function:拨打以下 function 时:

byte[] bytes = rsa.Encrypt(System.Text.UTF8Encoding.UTF8.GetBytes(stringToEncrypt), true);

I am now getting the error: bad length.我现在收到错误:长度错误。

With a smaller string it works, any ideas what the problem could be the string I am passing is under 200 characters.使用较小的字符串它可以工作,任何想法可能是我传递的字符串的问题都在 200 个字符以下。

RSA encryption is only mean for small amounts of data, the amount of data you can encrypt is dependent on the size of the key you are using, for example for 1024 bit RSA keys, and PKCS # 1 V1.5 padding, you can encrypt 117 bytes at most, with a 2048 RSA key, you can encrypt 245 bytes. RSA 加密仅适用于少量数据,您可以加密的数据量取决于您使用的密钥的大小,例如对于 1024 位 RSA 密钥和 PKCS #1 V1.5 填充,您可以加密最多117个字节,用2048个RSA密钥,可以加密245个字节。

There's a good reason for this, asymmetric encryption is computationally expensive.这有一个很好的理由,非对称加密在计算上很昂贵。 If you want to encrypt large amounts of data you should be using symmetric encryption.如果要加密大量数据,则应使用对称加密。 But what if you want non-repudiation?但是如果你想要不可否认性呢? Well what you then do is use both.那么你要做的就是同时使用两者。 You create a symmetric key and exchange it using asymmetric encryption, then that safely exchanged symmetric key to encrypt your large amounts of data.您创建一个对称密钥并使用非对称加密来交换它,然后安全地交换对称密钥来加密您的大量数据。 This is what SSL and WS-Secure use underneath the covers.这就是 SSL 和 WS-Secure 在幕后使用的内容。

For future searches regarding RSA bad length exceptions...对于未来关于 RSA 错误长度异常的搜索......

You can calculate the max number of bytes which can be encrypted with a particular key size with the following:您可以计算可以使用特定密钥大小加密的最大字节数,如下所示:

((KeySize - 384) / 8) + 37

However, if the optimal asymmetric encryption padding (OAEP) parameter is true, as it is in the original post, the following can be used to calculate the max bytes:但是,如果最佳非对称加密填充 (OAEP) 参数为真,如原始帖子中所述,则可以使用以下内容来计算最大字节数:

((KeySize - 384) / 8) + 7

The legal key sizes are 384 thru 16384 with a skip size of 8.合法的密钥大小为 384 到 16384,跳过大小为 8。

As explained above, the solution to the 'bad length' type exceptions is to hybridize the use of symmetric and asymmetric encryption, so that the size of the text you are encrypting is not constrained by the key size.如上所述,“错误长度”类型异常的解决方案是混合使用对称和非对称加密,以便您加密的文本大小不受密钥大小的限制。 You basically use RSA encryption to asymmetrically encrypt the random key .您基本上使用 RSA 加密对随机密钥进行非对称加密。

For encryption:对于加密:

  1. Generate a random key of the length required for symmetrical encryption technique such as AES or Rijndael.生成对称加密技术(例如 AES 或 Rijndael)所需长度的随机密钥。

  2. Symmetrically encrypt your text/data using AES/Rijndael using the random key generated in step 1.使用步骤 1 中生成的随机密钥,使用 AES/Rijndael 对称加密您的文本/数据。

  3. Using RSA, asymmetrically encrypt the random key generated in step 1.使用 RSA,对步骤 1 中生成的随机密钥进行非对称加密。

For decryption:对于解密:

  1. First decrypt the AES/Rijndael-generated random key using your private RSA key.首先使用您的私有 RSA 密钥解密 AES/Rijndael 生成的随机密钥。

  2. Then decrypt the original text/data using the RSA-decrypted random key然后使用 RSA 解密的随机密钥解密原始文本/数据

For a demonstration, you may wish to have a look this following example in C#:为了演示,您可能希望在 C# 中查看以下示例:

http://www.technical-recipes.com/2013/using-rsa-to-encrypt-large-data-files-in-c/ http://www.technical-recipes.com/2013/using-rsa-to-encrypt-large-data-files-in-c/

I faced the same challenge while doing 2048 RSA encryption of plain text having less than 200 characters.我在对少于 200 个字符的纯文本进行 2048 RSA 加密时遇到了同样的挑战。

In my opinion, we can achieve the target without getting into complexity of Symmetric or Asymmetric encryption, with following simple steps;在我看来,我们可以在不涉及对称或非对称加密的复杂性的情况下,通过以下简单的步骤来实现目标;

By doing so I managed to encrypt and decrypt 40x larger text通过这样做,我设法加密和解密了 40 倍大的文本

Encryption:加密:

  1. Compress the plain text by using *Zip() method and convert into array of bytes使用 *Zip() 方法压缩纯文本并转换为字节数组
  2. Encrypt with RSA使用 RSA 加密

Decryption:解密:

  1. Decrypt cypher text with RSA使用 RSA 解密密码文本
  2. un-compress decrypted data by using **Unzip() method使用 **Unzip() 方法解压缩解密数据

*byte[] bytes = Zip(stringToEncrypt); *byte[] bytes = Zip(stringToEncrypt); // Zip() method copied below // Zip() 方法复制到下面

**decryptedData = Unzip(decryptedBytes); **decryptedData = Unzip(decryptedBytes); // Unzip() method copied below // Unzip() 方法复制到下面


public static byte[] Zip(string str)
{
    var bytes = System.Text.Encoding.UTF8.GetBytes(str);    
    using (var msi = new MemoryStream(bytes))
    using (var mso = new MemoryStream())
    {
        using (var gs = new GZipStream(mso, CompressionMode.Compress))
        {                        
            CopyTo(msi, gs);
        }    
        return mso.ToArray();
    }
}
public static string Unzip(byte[] bytes)
{
    using (var msi = new MemoryStream(bytes))
    using (var mso = new MemoryStream())
    {
        using (var gs = new GZipStream(msi, CompressionMode.Decompress))
        {                     
            CopyTo(gs, mso);
        }    
        return System.Text.Encoding.UTF8.GetString(mso.ToArray());
    }
}

public static void CopyTo(Stream src, Stream dest)
    {
        byte[] bytes = new byte[4096];

        int cnt;

        while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0)
        {
            dest.Write(bytes, 0, cnt);
        }
    }
// [keySize] ÷ 8 - [11 bytes for padding] = Result
// Exsimple: [2048 key size] ÷ 8 - [11 bytes for padding] = 245
public static int GetSizeOutputEncryptOfKeySize(System.Security.Cryptography.RSA rsa) => (rsa.KeySize / 8) - 11;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM