RSA加密大文件

Posted

技术标签:

【中文标题】RSA加密大文件【英文标题】:RSA encrypting a large file 【发布时间】:2013-04-28 17:25:22 【问题描述】:

问题是我使用我想出的这段代码使用 rsa 加密了一个文件:

        for (int a = 0; a <= iterations; a++)
        
            byte[] plain;
            int rsaLen = rsa.KeySize / 8 - 11;
            int bytesLen = plain.Length;
            int block = bytesLen - rsaLen * a;

            //The last block in the text may not be a full block
            if (block > rsaLen )
                plain = new byte[maxRsaLength];
            else
                plainblock = new byte[block];

            Buffer.BlockCopy(plaintext, rsaLen * a, plain, 0, plain.Length);

            //purfoming the encryption
            ciphertext.Append(Convert.ToBase64String(rsa.Encrypt(plain, false)));
        

问题是当我尝试解密时,我必须将我放入 base 64 的密文转换为 base 64 块,但随后我从 RSAServiceProvider 的解密方法中得到了一个错误的长度异常。我一直在关注这个网站上写的例子: http://digitalsquid.co.uk/2009/01/rsa-in-cs/ 无济于事。我没有得到任何加密错误只是解密。我什至不能确定我是否正确地进行了加密。下面是我的解密循环:

   public string Decrypt(string ciphertext, string key = null)
    
        //checking for ciphertext. Exception raise if null
        if (String.IsNullOrEmpty(ciphertext)) throw new ArgumentNullException(ciphertext, "There is no ciphertext to decrypt.");

        //String holding the decrypted value
        string plaintext = String.Empty;

        //chanck is the user has provided a key. If not the use the one automatically generated
        string keyToUse = String.IsNullOrEmpty(key) ? privatekey : key;

        //set the key
        rsa.FromXmlString(keyToUse);

        //Determine the blocksizes for the iterations
        int blockSize = ((rsa.KeySize / 8) % 3 != 0) ? (((rsa.KeySize / 8) / 3) * 4) + 4 : ((rsa.KeySize / 8) / 3) * 4;

        int iterations = ciphertext.Length / blockSize;
        byte[] allPlaintextAsBytes = new byte[0];


        try
        
            for (int i = 0; i < iterations; i++)
            
                //to decrypt this we have to take the cipher text from a base 64 string an array.
                byte[] cipherTextAsBytes = Convert.FromBase64String(ciphertext.Substring(blockSize * i, blockSize));

                byte[] partialPlaintextAsBytes = rsa.Decrypt(cipherTextAsBytes, false);
            
        ....(Catch Exceptions down here)

我知道最好将文件拆分为 RSA IT。是的,通常您使用 RSA 将密钥加密为流密码(如 AES)并使用 AES 加密文件。这是我正在做的一个项目,所以我必须这样做。

提前感谢您的帮助。

【问题讨论】:

确保分配该项目的人指出这对可能不知道这一点的其他学生来说是愚蠢的。进行嵌套对称加密不仅仅是一种安全约定:使用 RSA 进行直接加密是非常不安全的。我不希望一代学生离开这个项目,认为这种做法无论如何都可以。 @MyseriousDan 我有点不同意。当然,这样做是愚蠢的。但是,“直接”RSA 加密是安全的。 是不是有点傻。使用 512 或 128 密钥加密是愚蠢的,但它可以帮助人们开始理解这些数字是如何工作的。他要求我这样做的原因是为了让我能够完成这项工作。到目前为止,通过执行这个项目,我了解到块密码不能加密大于模数的块。在我拿到这个项目之前我并不知道这一点。我可以有把握地说我不是专家,但那些专家不应该仅仅因为它和不寻常的做事方式就拒绝回答这个问题,甚至不回答它。问题是关于我写的代码不起作用而不是概念 哦,原则上我不是故意不回答问题。我不知道 C# 加密 API 的细节,所以在那里帮不上什么忙。 @DuncanJones 我不确定您所说的直接 RSA 加密是什么意思,但是做显而易见的事情(即,将明文提高到模块化能力)肯定是不安全的。第一个 iPhone 解锁是由 Apple 工程师(或他们与基带签约的任何人)实现的,他们不知道安全填充方案和 Bleichenbacher 对这类事情的攻击。 @MyseriousDan 我也不确定“直接”是什么意思——你在第一条评论中提到过。无论如何,如果我们假设“正常”的 RSA 加密涉及使用标准方案(例如 OAEP)填充明文,那么它是安全的。 【参考方案1】:

现实世界的 RSA 实现会进行填充,这会影响可以加密的明文的最大长度。

特别是,PKCS#1 填充(最常见的类型)仅支持长度为 k - 11 个字节的明文,其中 k 是密钥长度。 OAEP 填充仅接受不超过 k - 2 * 哈希长度 - 2 长的纯文本(OAEP 允许您更改正在使用的哈希算法)。

【讨论】:

以上是关于RSA加密大文件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用公钥加密openssl中的大文件

RSA加密和解密与大消息不一致

非对称加密的RSA算法如何通过golang来实现?

RSA 加密

javaWeb中RSA的加密使用

如何用VC++随机生成一个大素数(满足RSA算法)