如何在 C# 中使用 RSA 加密文件(大数据)

Posted

技术标签:

【中文标题】如何在 C# 中使用 RSA 加密文件(大数据)【英文标题】:how to use RSA to encrypt files (huge data) in C# 【发布时间】:2010-11-15 00:06:44 【问题描述】:

我是加密新手。我需要实现非对称加密算法,我认为它使用私钥/公钥。我开始使用 RSACryptoServiceProvider 的示例。可以加密小数据。但是当在相对较大的数据“2行”上使用它时,我得到异常 CryptographicException “Bad Length”!

//Create a new instance of RSACryptoServiceProvider.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())


    //Import the RSA Key information. This only needs
    //toinclude the public key information.
    //RSA.ImportParameters(RSAKeyInfo);
    byte[] keyValue = Convert.FromBase64String(publicKey);
    RSA.ImportCspBlob(keyValue);

    //Encrypt the passed byte array and specify OAEP padding.  
    //OAEP padding is only available on Microsoft Windows XP or
    //later.  
    encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding);

然后我发现了一些使用 CryptoStream 加密大数据(或文件)的示例,并且仅使用 DES 或 3DES 等对称算法,这些算法具有 CreateEncryptor 函数以返回 ICryptoTransform 作为 CryptoStream 构造函数的输入之一!! !

CryptoStream cStream = new CryptoStream(fStream,
                new TripleDESCryptoServiceProvider().CreateEncryptor(Key, IV),
                CryptoStreamMode.Write);

使用 RSA 加密文件的方法是什么?

【问题讨论】:

私有/公共算法不适合加密大数据。在实践中,它们用于在两方之间交换私钥,用于对称加密/解密大数据。 【参考方案1】:

RSA 只能加密比密钥长度短的数据块,所以你通常做的是

    生成 AES(或类似)所需长度正确的随机密钥。 使用 AES 或使用该密钥的类似方法加密您的数据 使用您的 RSA 密钥加密随机密钥

然后发布 2 和 3 的输出

解密

    使用您的 RSA 密钥解密 AES 密钥。 使用该 AES 密钥解密数据

【讨论】:

如果您这样做,那么唯一可以解密数据的人就是拥有您的 RSA 密钥对中的私钥的人。【参考方案2】:

正如其他答案中提到的,非对称加密仅用于加密小于其密钥大小的数据。

当需要在两个系统之间传输大量加密数据时,我实施的一个选项是拥有一个 RSA 密钥对,其公钥对于发送方和接收方都是已知的,然后当需要发送数据时,接收方会生成一个新的 RSA 密钥对,使用公共公钥加密该密钥对的公钥,并将加密的公钥发送给发送者。发送方使用自己的私钥解密接收方的公钥(接收方不需要知道,就像发送方不需要知道接收方生成的私钥一样),生成对称加密密钥,用对称密钥加密数据然后使用从接收方收到的公钥加密对称密钥。然后将加密的对称密钥和加密数据发送给接收方,接收方使用其生成的私钥解密对称密钥,然后解密数据。

您可以使用RSACryptoServiceProvider.ToXMLString()RSACryptoServiceProvider.FromXMLString() 方法将公共公钥作为XML 字符串文字存储在接收方应用程序中。

不要忘记,当您生成对称加密密钥以使用RNGCryptoServiceProvider() 来生成密钥时,它是一种更安全的生成(伪)随机数的方法。

另外,我强烈建议不要使用 3DES 作为对称加密算法,它已经过时并且开始显示其年龄。对 AesCryptoServiceProvicerRijndaelManaged 类使用 AES 对称加密。

【讨论】:

【参考方案3】:

通常,RSA 仅用于传输对称密钥(例如在流的开头),然后使用该密钥对批量数据进行加密。

非对称加密不足以传输大量数据。

【讨论】:

【参考方案4】:

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

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

((KeySize - 384) / 8) + 37

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

((KeySize - 384) / 8) + 7

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

【讨论】:

【参考方案5】:

RSA(以及所有公钥/私钥算法)的 .NET 实现不支持大数据块 - 因为这不是公钥/私钥的目标。

相反,您要做的是生成一个新的对称密钥并使用它来加密数据。然后您使用公钥/私钥加密对称密钥并安全地与对方交换。然后他们解密对称密钥并使用它来解密您的数据。

【讨论】:

【参考方案6】:

我们有:

MaxBlockSize=((KeySize - 384) / 8) + 37

MaxBlockSize=((KeySize - 384) / 8) + 7

所以,我们可以将数据分成若干块,然后对每个块进行加密,然后将它们合并

【讨论】:

以上是关于如何在 C# 中使用 RSA 加密文件(大数据)的主要内容,如果未能解决你的问题,请参考以下文章

全面解决.Net与Java互通时的RSA加解密问题,使用PEM格式的密钥文件

.NET Core加解密实战系列之——RSA非对称加密算法

如何将 Java RSA 公钥移植到 c# 加密功能?

基于C#的RSA非对称加密算法

解密 C# 中使用 RSA-OAEP 在 JavaScript 中加密的数据时出现 OAEP 填充错误

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