public static void Initialize(string inputFilePath, string outputFilePath, byte[] keyEncryptionKey) { byte[] dataEncryptionKey = new byte[Constants.EncryptionKeyLength]; try { byte[] encryptedHeader = FileHeaders.ReadEncryptedHeader(inputFilePath); byte[] nonce = FileHeaders.ReadNonce(inputFilePath); byte[] header = DecryptFileHeader(inputFilePath, encryptedHeader, nonce, keyEncryptionKey); if (header == null) { throw new ArgumentException("Incorrect password/keyfile or this file has been tampered with."); } ChunkHandling.ValidateKeyCommitmentBlock(header); int lastChunkLength = FileHeaders.GetLastChunkLength(header); int fileNameLength = FileHeaders.GetFileNameLength(header); dataEncryptionKey = FileHeaders.GetDataEncryptionKey(header); Utilities.ZeroArray(header); using (var inputFile = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.SequentialScan)) using (var outputFile = new FileStream(outputFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.SequentialScan)) { nonce = Sodium.Utilities.Increment(nonce); byte[] additionalData = ChunkHandling.GetPreviousPoly1305Tag(encryptedHeader); Decrypt(inputFile, outputFile, nonce, dataEncryptionKey, additionalData, lastChunkLength); } Finalize(inputFilePath, outputFilePath, fileNameLength); } catch (Exception ex) when(ExceptionFilters.Cryptography(ex)) { Utilities.ZeroArray(dataEncryptionKey); throw; } }
public static void Initialize(FileStream inputFile, string outputFilePath, byte[] ephemeralPublicKey, byte[] keyEncryptionKey) { var dataEncryptionKey = new byte[Constants.EncryptionKeyLength]; try { byte[] encryptedHeader = FileHeaders.ReadEncryptedHeader(inputFile); byte[] nonce = FileHeaders.ReadNonce(inputFile); byte[] header = DecryptFileHeader(inputFile, ephemeralPublicKey, encryptedHeader, nonce, keyEncryptionKey); if (header == null) { throw new ArgumentException("Incorrect password/key or this file has been tampered with."); } int lastChunkLength = FileHeaders.GetLastChunkLength(header); int fileNameLength = FileHeaders.GetFileNameLength(header); dataEncryptionKey = FileHeaders.GetDataEncryptionKey(header); CryptographicOperations.ZeroMemory(header); using (var outputFile = new FileStream(outputFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.SequentialScan)) { nonce = Utilities.Increment(nonce); byte[] additionalData = ChunkHandling.GetPreviousTag(encryptedHeader); Decrypt(inputFile, outputFile, nonce, dataEncryptionKey, additionalData, lastChunkLength); } string inputFilePath = inputFile.Name; inputFile.Dispose(); Finalize(inputFilePath, outputFilePath, fileNameLength); } catch (Exception ex) when(ExceptionFilters.Cryptography(ex)) { CryptographicOperations.ZeroMemory(dataEncryptionKey); if (!(ex is ArgumentException)) { FileHandling.DeleteFile(outputFilePath); } throw; } }