Я хочу зашифровать большой файл (скажем, 64 ГБ) наиболее эффективным способом в .NET.AES-Encrypt-then-MAC большой файл с .NET
Как бы это реализовать:
- Создать экземпляр
AesManaged
для шифрования потока файла (чтение 64 ГБ) - Сохранить этот поток на диске (потому что это большой, чтобы держать в память) (запись 64 Гб)
- Создать экземпляр
HMACSHA512
для вычисления хэша сохраненного файла (чтение 64 ГБ) - Сохранить зашифрованные данные с IV на диск (чтение & записи 64 ГБ)
Упрощенная C# Код:
using (var aesManaged = new AesManaged())
{
using (var msEncrypt = File.OpenWrite(@"C:\Temp\bigfile.bin.tmp"))
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
File.OpenRead(@"C:\Temp\bigfile.bin").CopyTo(csEncrypt);
new MemoryStream(iv).CopyTo(csEncrypt);
}
}
}
using (var hmac = new HMACSHA512(hmacKey))
{
hmacHash = hmac.ComputeHash(File.OpenRead(@"C:\Temp\bigfile.bin.tmp"));
}
byte[] headerBytes;
using (var memoryStream = new MemoryStream())
{
var header = new Header
{
IV = iv,
HmacHash = hmacHash
};
Serializer.Serialize(memoryStream, header);
headerBytes = memoryStream.ToArray();
}
using (var newfile = File.OpenWrite(@"C:\Temp\bigfile.bin.enc"))
{
new MemoryStream(MagicBytes).CopyTo(newfile);
new MemoryStream(BitConverter.GetBytes(headerBytes.Length)).CopyTo(newfile);
new MemoryStream(headerBytes).CopyTo(newfile);
File.OpenRead(@"C:\Temp\bigfile.bin.tmp").CopyTo(newfile);
}
Эта реализация имеет недостаток что я создал второй файл и что я прочитал несколько раз 64 Гб с диска.
Это необходимо? Как свести к минимуму дисковое распределение ввода-вывода и вытеснения?
Нет, это не обязательно, когда сделано правильно. Кроме того, шаг 4 является странным, потому что IV должен быть создан, прежде чем пытаться зашифровать. Обычно записывать IV перед зашифрованным текстом в файл. –