[英]AES 256 file encryption c#
我似乎找不到使用 AES 256 加密在 c# 中加密文件的干凈示例
有人有一些示例代碼嗎?
這是上述問題的答案
UnicodeEncoding ue = new UnicodeEncoding();
byte[] key = ue.GetBytes(password);
string cryptFile = outputFile;
using (FileStream fileCrypt = new FileStream(cryptFile, FileMode.Create))
{
using (AesManaged encrypt = new AesManaged())
{
using (CryptoStream cs = new CryptoStream(fileCrypt, encrypt.CreateEncryptor(key, key), CryptoStreamMode.Write))
{
using (FileStream fileInput = new FileStream(inputFile, FileMode.Open))
{
encrypt.KeySize = 256;
encrypt.BlockSize = 128;
int data;
while ((data = fileInput.ReadByte()) != -1)
cs.WriteByte((byte)data);
}
}
}
}
我不是安全專家,除了小文件外,我沒有對此進行過測試,但這是我使用 .NET 6 進行的 AES-256 文件加密的現代化和完整版本:
using System.Security.Cryptography;
using System.Text;
namespace Core.Encryption;
/// <summary>
/// Encrypts and decrypts files using AES-256.
/// String keys are encoded using UTF8.
/// </summary>
public static class FileEncryptor
{
private const int AesKeySize = 256;
private const int AesBlockSize = 128;
public const int KeySizeInBytes = AesKeySize / 8;
/// <summary>
/// Encrypts a file using a 32 character key.
/// </summary>
public static Task EncryptAsync(string inputFilePath, string outputFilePath, string key, CancellationToken token = default)
{
if (string.IsNullOrWhiteSpace(key))
{
throw new ArgumentException("Key cannot be empty!", nameof(key));
}
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
return EncryptAsync(inputFilePath, outputFilePath, keyBytes, token);
}
public static async Task EncryptAsync(string inputFilePath, string outputFilePath, byte[] keyBytes, CancellationToken token = default)
{
if (!File.Exists(inputFilePath))
{
throw new ArgumentException("Input file does not exist!", nameof(inputFilePath));
}
if (keyBytes.Length != KeySizeInBytes)
{
throw new ArgumentException("Key must be 32 bytes (256 bits) in length!", nameof(keyBytes));
}
using var aes = Aes.Create();
aes.BlockSize = AesBlockSize;
aes.KeySize = AesKeySize;
aes.Key = keyBytes;
await using FileStream outFileStream = new(outputFilePath, FileMode.Create);
// Write initialization vector to beginning of file
await outFileStream.WriteAsync(aes.IV.AsMemory(0, aes.IV.Length), token);
ICryptoTransform encryptor = aes.CreateEncryptor();
await using CryptoStream cryptoStream = new(
outFileStream,
encryptor,
CryptoStreamMode.Write);
await using var inputFileStream = new FileStream(inputFilePath, FileMode.Open);
await inputFileStream.CopyToAsync(cryptoStream, token);
}
/// <summary>
/// Decrypts a file using a 32 character key.
/// </summary>
public static Task DecryptAsync(string inputFilePath, string outputFilePath, string key, CancellationToken token = default)
{
if (string.IsNullOrWhiteSpace(key))
{
throw new ArgumentException("Key cannot be empty!", nameof(key));
}
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
return DecryptAsync(inputFilePath, outputFilePath, keyBytes, token);
}
public static async Task DecryptAsync(string inputFilePath, string outputFilePath, byte[] keyBytes, CancellationToken token = default)
{
if (!File.Exists(inputFilePath))
{
throw new ArgumentException("Input file does not exist!", nameof(inputFilePath));
}
if (keyBytes.Length != KeySizeInBytes)
{
throw new ArgumentException("Key must be 32 bytes (256 bits) in length!", nameof(keyBytes));
}
await using var inputFileStream = new FileStream(inputFilePath, FileMode.Open);
// Read IV from beginning of file
const int blockSizeInBytes = AesBlockSize / 8;
var initializationVector = new byte[blockSizeInBytes];
int ivBytesRead = await inputFileStream.ReadAsync(initializationVector.AsMemory(0, blockSizeInBytes), token);
if (ivBytesRead != initializationVector.Length)
{
throw new ArgumentException("Failed to read initialization vector from input file!", nameof(inputFilePath));
}
using var aes = Aes.Create();
aes.BlockSize = AesBlockSize;
aes.IV = initializationVector;
aes.KeySize = AesKeySize;
aes.Key = keyBytes;
ICryptoTransform decryptor = aes.CreateDecryptor();
await using CryptoStream cryptoStream = new(
inputFileStream,
decryptor,
CryptoStreamMode.Read);
await using FileStream outFileStream = new(outputFilePath, FileMode.Create);
await cryptoStream.CopyToAsync(outFileStream, token);
}
}
我也沒有測試取消,但我不明白為什么它不應該工作。 不用說,您應該進行自己的測試 :-)
用法:
var inputFile = @"C:\tmp\test.txt";
var outputFile = @"C:\tmp\test.encrypted";
var password = "abcde-fghij-klmno-pqrst-uvwxy-z0"; // must be 32 chars (256 / 8 = 32 bytes)
await FileEncryptor.EncryptAsync(inputFile, outputFile, password);
await FileEncryptor.DecryptAsync(outputFile, @"C:\tmp\decrypted.txt", password);
為了支持多種密鑰大小,我想我們可以像 IV 一樣將它寫入文件的開頭,但對於我的要求,這已經足夠了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.