【问题标题】:RSA Encryption, getting bad lengthRSA 加密,长度变差
【发布时间】:2010-12-02 13:54:12
【问题描述】:

调用以下函数时:

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

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

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

【问题讨论】:

    标签: c# encryption rsa encryption-asymmetric


    【解决方案1】:

    在对少于 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);
            }
        }
    

    【讨论】:

    • 嗨,CopyTo 是做什么的?
    • @foyss 感谢您的指出,我在答案中添加了 CopyTo() 方法
    【解决方案2】:

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

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

    【讨论】:

    • 你知道我应该使用什么 .net 对象来加密最多 500 个字符的字符串吗?
    • 任何对称算法。这取决于您要加密它的目的。可能最好将其表述为另一个问题。
    • 不仅仅是计算量大。 RSA 算法加密一个特定的数字,产生另一个数字。由于算法的工作方式,该数字有一个最大大小。密钥越宽,它可以加密的最大数字越大。 1024 位密钥是 128 字节宽的数字,2048 位密钥是 256 字节。每个都可以加密一个最大宽度比它自己的宽度小一点的数字。如果输入的数字太大,那么输出将与加密范围内的另一个数字相同,并且无法判断哪个是实际输入。
    • 当我第二次尝试加密 same 数据时出现此异常。知道是什么原因造成的吗??
    • @mrid 可能是因为密文(加密输出)比原始纯文本大,所以虽然纯文本对于您的算法来说足够小,但密文却不是。
    【解决方案3】:

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

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

    ((KeySize - 384) / 8) + 37
    

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

    ((KeySize - 384) / 8) + 7
    

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

    【讨论】:

    【解决方案4】:

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

    对于加密:

    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-07-16
      • 2016-07-15
      • 2020-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多