加密/解密大文件(.NET)

我必须加密,存储然后解密大文件。 这样做的最佳方式是什么? 我听说RSA加密很昂贵,建议使用RSA加密AES密钥,然后使用AES密钥加密大文件。 任何带有示例的建议都会很棒。

这可能有所帮助

/// Encrypts a file using Rijndael algorithm. /// /// /// private void EncryptFile(string inputFile, string outputFile) { try { string password = @"myKey123"; // Your Key Here UnicodeEncoding UE = new UnicodeEncoding(); byte[] key = UE.GetBytes(password); string cryptFile = outputFile; FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create); RijndaelManaged RMCrypto = new RijndaelManaged(); CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write); FileStream fsIn = new FileStream(inputFile, FileMode.Open); int data; while ((data = fsIn.ReadByte()) != -1) cs.WriteByte((byte)data); fsIn.Close(); cs.Close(); fsCrypt.Close(); } catch { MessageBox.Show("Encryption failed!", "Error"); } } /// /// Decrypts a file using Rijndael algorithm. /// /// /// private void DecryptFile(string inputFile, string outputFile) { { string password = @"myKey123"; // Your Key Here UnicodeEncoding UE = new UnicodeEncoding(); byte[] key = UE.GetBytes(password); FileStream fsCrypt = new FileStream(inputFile, FileMode.Open); RijndaelManaged RMCrypto = new RijndaelManaged(); CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(key, key), CryptoStreamMode.Read); FileStream fsOut = new FileStream(outputFile, FileMode.Create); int data; while ((data = cs.ReadByte()) != -1) fsOut.WriteByte((byte)data); fsOut.Close(); cs.Close(); fsCrypt.Close(); } } 

来源: http : //www.codeproject.com/Articles/26085/File-Encryption-and-Decryption-in-C

一个有机体的大小是另一个娇小的,虽然我们看到它时都知道它们很贵。 眨眼眨眼。

尝试在您的环境中对以下内容进行基准测试,并查看您所处的位置:

编辑2/13/2012:代码已经更新,因为我变得(不知不觉)更聪明,并且还注意到一些已经悄悄进入的’cut’n’paste错误.Mea culpa。

 using System; using System.IO; using System.Security.Cryptography; using System.Text; ... // Rfc2898DeriveBytes constants: public readonly byte[] salt = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Must be at least eight bytes. MAKE THIS SALTIER! public const int iterations = 1042; // Recommendation is >= 1000. /// Decrypt a file. /// NB: "Padding is invalid and cannot be removed." is the Universal CryptoServices error. Make sure the password, salt and iterations are correct before getting nervous. /// The full path and name of the file to be decrypted. /// The full path and name of the file to be output. /// The password for the decryption. /// The salt to be applied to the password. /// The number of iterations Rfc2898DeriveBytes should use before generating the key and initialization vector for the decryption. public void DecryptFile(string sourceFilename, string destinationFilename, string password, byte[] salt, int iterations) { AesManaged aes = new AesManaged(); aes.BlockSize = aes.LegalBlockSizes[0].MaxSize; aes.KeySize = aes.LegalKeySizes[0].MaxSize; // NB: Rfc2898DeriveBytes initialization and subsequent calls to GetBytes must be eactly the same, including order, on both the encryption and decryption sides. Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(password, salt, iterations); aes.Key = key.GetBytes(aes.KeySize / 8); aes.IV = key.GetBytes(aes.BlockSize / 8); aes.Mode = CipherMode.CBC; ICryptoTransform transform = aes.CreateDecryptor(aes.Key, aes.IV); using (FileStream destination = new FileStream(destinationFilename, FileMode.CreateNew, FileAccess.Write, FileShare.None)) { using (CryptoStream cryptoStream = new CryptoStream(destination, transform, CryptoStreamMode.Write)) { try { using (FileStream source = new FileStream(sourceFilename, FileMode.Open, FileAccess.Read, FileShare.Read)) { source.CopyTo(cryptoStream); } } catch (CryptographicException exception) { if (exception.Message == "Padding is invalid and cannot be removed.") throw new ApplicationException("Universal Microsoft Cryptographic Exception (Not to be believed!)", exception); else throw; } } } } /// Encrypt a file. /// The full path and name of the file to be encrypted. /// The full path and name of the file to be output. /// The password for the encryption. /// The salt to be applied to the password. /// The number of iterations Rfc2898DeriveBytes should use before generating the key and initialization vector for the decryption. public void EncryptFile(string sourceFilename, string destinationFilename, string password, byte[] salt, int iterations) { AesManaged aes = new AesManaged(); aes.BlockSize = aes.LegalBlockSizes[0].MaxSize; aes.KeySize = aes.LegalKeySizes[0].MaxSize; // NB: Rfc2898DeriveBytes initialization and subsequent calls to GetBytes must be eactly the same, including order, on both the encryption and decryption sides. Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(password, salt, iterations); aes.Key = key.GetBytes(aes.KeySize / 8); aes.IV = key.GetBytes(aes.BlockSize / 8); aes.Mode = CipherMode.CBC; ICryptoTransform transform = aes.CreateEncryptor(aes.Key, aes.IV); using (FileStream destination = new FileStream(destinationFilename, FileMode.CreateNew, FileAccess.Write, FileShare.None)) { using (CryptoStream cryptoStream = new CryptoStream(destination, transform, CryptoStreamMode.Write)) { using (FileStream source = new FileStream(sourceFilename, FileMode.Open, FileAccess.Read, FileShare.Read)) { source.CopyTo(cryptoStream); } } } } 

通常,当数据在一台计算机(如服务器)上加密,然后由另一台计算机(客户端)解密时,将使用您描述的策略。 服务器将使用对称密钥加密(用于性能)使用新生成的密钥加密数据,并使用公钥(匹配客户端的私钥)加密此对称密钥。 服务器向客户端发送加密数据和加密对称密钥。 客户端可以使用其私钥解密对称密钥,然后使用此对称密钥来解密数据。 如果您正在加密和解密同一台计算机上的数据,则使用RSA和AES可能没有意义,因为您不会尝试将加密密钥传递给另一台计算机。

就像你听到的那样,非对称加密技术(如RSA)比对称加密技术(例如AES)慢得多,但它确实具有优势(更简单的密钥管理,例如单个私钥保护)。

密钥(双关语)是利用两者的优点(非对称私钥和对称速度)而忽略了另一方的不便(许多密钥和慢速)。

您可以通过每个文件使用一次RSA(没有巨大的性能影响)来加密用于加密(更快)大文件的(对称)密钥。 这种对称密钥的包装允许您只管理一个私钥。

这是我旧的(但仍然是真实的) 博客文章的链接,它提供了一个使用C#和.NET框架(Microsoft Mono)的例子。