如何在C#中使用AES加密算法对文件进行加密和解

如果用户的文件包含敏感信息, 则可以对其进行加密, 以便除了用户本身之外, 其他任何人都不能打开该文件。加密文件会使任何人在没有密码的情况下都难以访问和阅读它们。如果你是项目中的加密主题, 我们将在本文中向你展示如何轻松地使用AES算法对文件进行加密和解密。

注意

本文介绍了一种使用诸如加密和解密之类的简单方法轻松快速地对文件进行加密和解密的方法。它们是从Stack Overflow, Security Exchange和MSDN官方网站等不同来源重新收集信息的结果。

1.导入所需的类型

为了在你的项目上处理AES加密算法以加密和解密文件, 请导入以下2种必需的类型:

using System.Security.Cryptography; using System.Runtime.InteropServices;

在类顶部对InteropServices的引用将使你以后可以在类中使用DllImport方法。

2.创建加密和解密方法

你需要将以下3种方法添加到你的类中(或在新类中创建它们, 然后将它们导入你的类中):

GenerateRandomSalt:此方法创建随机盐。此功能是可自定义的, 你可以根据需要对其进行修改以创建自己的盐。

FileEncrypt:此方法使用普通密码加密现有文件。

FileDecrypt:此方法使用纯密码作为参数, 使用FileEncrypt方法解密以前加密的文件。

ZeroMemory:此方法将用于从内存中删除密码, 从而提高加密的安全性。不必要, 但建议使用。

该方法将在第3步中使用和说明, 目前, 将这些方法复制并包含在你的项目中:

// Call this function to remove the key from memory after use for security [DllImport("KERNEL32.DLL", EntryPoint = "RtlZeroMemory")] public static extern bool ZeroMemory(IntPtr Destination, int Length); /// <summary> /// Creates a random salt that will be used to encrypt your file. This method is required on FileEncrypt. /// </summary> /// <returns></returns> public static byte[] GenerateRandomSalt() { byte[] data = new byte[32]; using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) { for (int i = 0; i < 10; i++) { // Fille the buffer with the generated data rng.GetBytes(data); } } return data; } /// <summary> /// Encrypts a file from its path and a plain password. /// </summary> /// <param></param> /// <param></param> private void FileEncrypt(string inputFile, string password) { //http://stackoverflow.com/questions/27645527/aes-encryption-on-large-files //generate random salt byte[] salt = GenerateRandomSalt(); //create output file name FileStream fsCrypt = new FileStream(inputFile + ".aes", FileMode.Create); //convert password string to byte arrray byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(password); //Set Rijndael symmetric encryption algorithm RijndaelManaged AES = new RijndaelManaged(); AES.KeySize = 256; AES.BlockSize = 128; AES.Padding = PaddingMode.PKCS7; //http://stackoverflow.com/questions/2659214/why-do-i-need-to-use-the-rfc2898derivebytes-class-in-net-instead-of-directly //"What it does is repeatedly hash the user password along with the salt." High iteration counts. var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000); AES.Key = key.GetBytes(AES.KeySize / 8); AES.IV = key.GetBytes(AES.BlockSize / 8); //Cipher modes: AES.Mode = CipherMode.CFB; // write salt to the begining of the output file, so in this case can be random every time fsCrypt.Write(salt, 0, salt.Length); CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateEncryptor(), CryptoStreamMode.Write); FileStream fsIn = new FileStream(inputFile, FileMode.Open); //create a buffer (1mb) so only this amount will allocate in the memory and not the whole file byte[] buffer = new byte[1048576]; int read; try { while ((read = fsIn.Read(buffer, 0, buffer.Length)) > 0) { Application.DoEvents(); // -> for responsive GUI, using Task will be better! cs.Write(buffer, 0, read); } // Close up fsIn.Close(); } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } finally { cs.Close(); fsCrypt.Close(); } } /// <summary> /// Decrypts an encrypted file with the FileEncrypt method through its path and the plain password. /// </summary> /// <param></param> /// <param></param> /// <param></param> private void FileDecrypt(string inputFile, string outputFile, string password) { byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(password); byte[] salt = new byte[32]; FileStream fsCrypt = new FileStream(inputFile, FileMode.Open); fsCrypt.Read(salt, 0, salt.Length); RijndaelManaged AES = new RijndaelManaged(); AES.KeySize = 256; AES.BlockSize = 128; var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000); AES.Key = key.GetBytes(AES.KeySize / 8); AES.IV = key.GetBytes(AES.BlockSize / 8); AES.Padding = PaddingMode.PKCS7; AES.Mode = CipherMode.CFB; CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateDecryptor(), CryptoStreamMode.Read); FileStream fsOut = new FileStream(outputFile, FileMode.Create); int read; byte[] buffer = new byte[1048576]; try { while ((read = cs.Read(buffer, 0, buffer.Length)) > 0) { Application.DoEvents(); fsOut.Write(buffer, 0, read); } } catch (CryptographicException ex_CryptographicException) { Console.WriteLine("CryptographicException error: " + ex_CryptographicException.Message); } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } try { cs.Close(); } catch (Exception ex) { Console.WriteLine("Error by closing CryptoStream: " + ex.Message); } finally { fsOut.Close(); fsCrypt.Close(); } }

它们不一定是完美的, 可以(并且需要)对其进行修改以处理更多异常, 以防它们出现以及你如何使用应用程序。

3.使用方法

从所需的方法中, 你显然只需要使用其中2个(FileEncrypt和FileDecrypt), 并且其中1个是可选的, 第四个(GenerateRandomSalt)由FileEncrypt方法在内部使用。

加密档案

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/f453e85f7b23e460344fb3305a22f8dc.html