C#中如何使用RSA加密文件(海量数据)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1199058/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to use RSA to encrypt files (huge data) in C#
提问by ala
I'm new to encryption. I need to implement asymmetric encryption algorithm, which i think it uses private/public key. I started using a sample of RSACryptoServiceProvider. it was ok with small data to encrypt. But when using it on relatively larger data "2 lines", i get the exception CryptographicException "Bad Length"!
我是加密新手。我需要实现非对称加密算法,我认为它使用私钥/公钥。我开始使用 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);
}
Then I found some samples of encrypting large data (or files) by using CryptoStream, and only use symmetric algorithms like DES or 3DES, which have the function CreateEncryptor to return ICryptoTransform as one of the input to the constructor of CryptoStream!!!
然后我找到了一些使用CryptoStream加密大数据(或文件)的示例,并且只使用对称算法如DES或3DES,它们具有函数CreateEncryptor返回ICryptoTransform作为CryptoStream构造函数的输入之一!!!
CryptoStream cStream = new CryptoStream(fStream,
new TripleDESCryptoServiceProvider().CreateEncryptor(Key, IV),
CryptoStreamMode.Write);
What is the way to encrypt files using RSA?
使用 RSA 加密文件的方法是什么?
采纳答案by Joe Kuemerle
As mentioned in other answers asymmetric encryption is only designed for encrypting data smaller than its key size.
正如其他答案中提到的,非对称加密仅用于加密小于其密钥大小的数据。
One option that I have implemented when needing to transfer large amounts of encrypted data between two systems is to have an RSA keypair whose public key is known to both the sender and the receiver then when data needs to be sent the receiver generates a new RSA keypair, encrypts the public key of that keypair with the common public key and sends the encrypted public key to the sender. The sender decrypts the receivers public key using its private key (which the receiver does not need to know, just as the sender does not need to know the receivers generated private key), generates a symmetric encryption key, encrypts the data with the symmetric key and then encrypts the symmetric key using the public key received from the receiver. Both the encrypted symmetric key and the encrypted data are then sent to the receiver which uses its generated private key to decrypt the symmetric key and then decrypts the data.
当需要在两个系统之间传输大量加密数据时,我实施的一种选择是拥有一个 RSA 密钥对,其公钥为发送方和接收方都知道,然后当需要发送数据时,接收方生成一个新的 RSA 密钥对, 使用公共公钥加密该密钥对的公钥,并将加密的公钥发送给发送方。发送方使用其私钥(接收方不需要知道,就像发送方不需要知道接收方生成的私钥一样)解密接收方的公钥,生成对称加密密钥,使用对称密钥对数据进行加密然后使用从接收方收到的公钥加密对称密钥。
You can use the RSACryptoServiceProvider.ToXMLString()
and RSACryptoServiceProvider.FromXMLString()
methods to store the common public key as an XML string literal in the receiver application.
您可以使用RSACryptoServiceProvider.ToXMLString()
和RSACryptoServiceProvider.FromXMLString()
方法将公共公钥作为 XML 字符串文字存储在接收器应用程序中。
Don't forget, when you generate the symmetric encryption key to use RNGCryptoServiceProvider()
to generate the key as it is a much more secure method of generating (pseudo) random numbers.
不要忘记,当您生成RNGCryptoServiceProvider()
用于生成密钥的对称加密密钥时,因为它是一种更安全的生成(伪)随机数的方法。
Also, I strongly recommend against using 3DES as your symmetric encryption algorithm, it is old and starting to show its age. Use AES symmetric encryption with either the AesCryptoServiceProvicer
or RijndaelManaged
classes.
此外,我强烈建议不要使用 3DES 作为您的对称加密算法,它已经过时并开始显示其年龄。对AesCryptoServiceProvicer
或RijndaelManaged
类使用 AES 对称加密。
回答by Henk Holterman
Usually, RSA is only used to transfer a symmetric key (at the start of the stream for example) and then the bulk data is encrypted with that key.
通常,RSA 仅用于传输对称密钥(例如在流的开头),然后使用该密钥对批量数据进行加密。
Asymmetric encryption isn't efficient enough to transfer a lot of data.
非对称加密的效率不足以传输大量数据。
回答by blowdart
The .NET implementations of RSA (and all public/private key algorithms) do not support large blocks of data - because that's not the aim of public/private key.
RSA(以及所有公钥/私钥算法)的 .NET 实现不支持大数据块 - 因为这不是公钥/私钥的目的。
Instead what you would do is generate a new symmetric key and use that to encrypt the data. Then you use public/private key to encrypt the symmetric key and exchange it with the other party securely. They then decrypt the symmetric key and use it to unencrypt your data.
相反,您要做的是生成一个新的对称密钥并使用它来加密数据。然后您使用公钥/私钥加密对称密钥并安全地与另一方交换。然后他们解密对称密钥并使用它来解密您的数据。
回答by jcoder
RSA can only encrypt data blocks that are shorter than the key length so what you normally do is
RSA 只能加密比密钥长度短的数据块,所以你通常做的是
- Generate a random key of the correct length required for AES (or similar).
- Encrypt your data using AES or similar using that key
- Encrypt the random key using your RSA key
- 生成 AES(或类似)所需的正确长度的随机密钥。
- 使用该密钥使用 AES 或类似方法加密您的数据
- 使用您的 RSA 密钥加密随机密钥
Then you publish both the outputs from 2 and 3
然后发布 2 和 3 的输出
To decrypt
解密
- Decrypt the AES key using your RSA key.
- Decrypt the data using that AES key
- 使用您的 RSA 密钥解密 AES 密钥。
- 使用该 AES 密钥解密数据
回答by ObjectType
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
((KeySize - 384) / 8) + 37
However, if the optimal asymmetric encryption padding (OAEP) parameter is true, the following can be used to calculate the max bytes:
但是,如果最佳非对称加密填充 (OAEP) 参数为真,则可以使用以下方法计算最大字节数:
((KeySize - 384) / 8) + 7
((KeySize - 384) / 8) + 7
The legal key sizes are 384 thru 16384 with a skip size of 8.
合法的密钥大小为 384 到 16384,跳过大小为 8。
回答by kazem
we have:
我们有:
MaxBlockSize=((KeySize - 384) / 8) + 37
OR
或者
MaxBlockSize=((KeySize - 384) / 8) + 7
so, we can divide Data to some blocks and then encrypt each one and then merge them
所以,我们可以将数据分成一些块,然后对每个块进行加密,然后合并它们