2016-07-27 7 views
0

.NETで最も効率的な方法で大きなファイル(64 GBと言う)を暗号化したい。私はこれを実装する方法をAES-Encrypt-then-MACの大容量ファイル

  1. を、それが中に保持するために大になるため(ディスクに保存
  2. (64ギガバイトを読む)ファイルのストリームを暗号化するために、このストリームをAesManagedのインスタンスを作成します。メモリ)(64ギガバイトを書く)
  3. 保存されたファイルのハッシュを計算するためにHMACSHA512のインスタンスを作成します(64ギガバイトを読む)
  4. 保存ディスクに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); 
} 

この実装では、私2番目のファイルを作成し、私は、ディスクからの複数回の64ギガバイトを読んその欠点を持っています。

必要ですか?ディスクIOとRAM割り当てを最小限に抑えるには?

+0

いいえ、正しく行われている必要はありません。また、暗号化しようとする前にIVを作成する必要があるため、手順4は奇妙です。暗号文の前のIVをファイルに書き込むのは一般的です。 –

答えて

2

私はいつもCryptoStreamが間違っているので、私の擬似コードを間違えてください。基本的な考え方は、平文を暗号化を行う暗号化ストリームにコピーし、暗号化を行う暗号化ストリームにデータを書き込んだ後、普通の古いファイルストリームに書き込みます。

using(var encryptedFileStream = File.OpenWrite("..."))   
using(var macCryptoStream = new CryptoStream(encryptedFileStream, mac, CryptoStreamMode.Write)) 
using(var encryptCryptoStream = new CryptoStream(macCryptoStream, encryptor, CryptoStreamMode.Write)) 
using(var inputFileStream = File.OpenRead("...")) 
    inputFileStream.CopyTo(encryptCryptoStream); 

この方法では、64 Gbを1回だけ通過する必要があります。

さて、あなたは何とか自分の暗号化されたファイルの先頭にIVおよびMACを格納する必要がありますので、それを最初に「サイズ変更する」:

using(var encryptedFileStream = File.OpenWrite("...")) 
{ 
    var offset = YourMagicHeaderLength + IvLength + MacLength; 
    encryptedFileStream.SetLength(offset); 
    encryptedFileStream.Position = offset; 

    // The rest of the code goes here 
} 

、その後、MACを暗号化して計算した後に巻き戻し非常に始まり、それらを書き出します。

+0

hmacにデータを追加したいが、結果のファイルストリームにデータを追加したくない場合はどうすればよいですか? –

関連する問題