66

调用以下函数时:

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

我现在收到错误:长度错误。

使用较小的字符串它可以工作,任何问题可能是我传递的字符串的任何想法都在 200 个字符以下。

4

4 回答 4

95

RSA 加密仅适用于少量数据,您可以加密的数据量取决于您使用的密钥的大小,例如对于 1024 位 RSA 密钥和 PKCS #1 V1.5 填充,您可以加密最多 117 字节,使用 2048 的 RSA 密钥,可以加密 245 字节。

这有一个很好的理由,非对称加密的计算成本很高。如果要加密大量数据,则应使用对称加密。但是,如果您想要不可否认性怎么办?那么你要做的就是同时使用两者。您创建一个对称密钥并使用非对称加密交换它,然后安全地交换对称密钥来加密您的大量数据。这就是 SSL 和 WS-Secure 在幕后使用的东西。

于 2009-09-30T08:41:59.140 回答
56

对于未来有关 RSA 错误长度异常的搜索...

您可以使用以下公式计算可以使用特定密钥大小加密的最大字节数:

((KeySize - 384) / 8) + 37

但是,如果最佳非对称加密填充 (OAEP) 参数为真,如原始帖子中所述,则可使用以下公式计算最大字节数:

((KeySize - 384) / 8) + 7

合法的密钥大小为 384 到 16384,跳过大小为 8。

于 2010-07-15T06:56:12.083 回答
19

如上所述,“错误长度”类型异常的解决方案是混合使用对称和非对称加密,以便您加密的文本大小不受密钥大小的限制。您基本上使用 RSA 加密对随机密钥进行非对称加密。

对于加密:

  1. 生成对称加密技术(如 AES 或 Rijndael)所需长度的随机密钥。

  2. 使用步骤 1 中生成的随机密钥,使用 AES/Rijndael 对称加密您的文本/数据。

  3. 使用 RSA,对步骤 1 中生成的随机密钥进行非对称加密。

对于解密:

  1. 首先使用您的私有 RSA 密钥解密 AES/Rijndael 生成的随机密钥。

  2. 然后使用 RSA 解密的随机密钥解密原始文本/数据

对于演示,您可能希望查看以下 C# 示例:

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

于 2013-11-03T21:17:15.983 回答
5

在对少于 200 个字符的纯文本进行 2048 RSA 加密时,我遇到了同样的挑战。

在我看来,我们可以在不涉及对称或非对称加密的复杂性的情况下实现目标,只需以下简单步骤;

通过这样做,我设法加密和解密了 40 倍大的文本

加密:

  1. 使用 *Zip() 方法压缩纯文本并转换为字节数组
  2. 使用 RSA 加密

解密:

  1. 使用 RSA 解密密码文本
  2. 使用 **Unzip() 方法解压缩解密数据

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

**decryptedData = Unzip(decryptedBytes); // 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);
        }
    }
于 2019-11-19T08:54:15.950 回答