예제 #1
0
        public static byte[] GetAdditionalData(string inputFilePath)
        {
            byte[] magicBytes    = FileHeaders.ReadMagicBytes(inputFilePath);
            byte[] formatVersion = FileHeaders.ReadFileFormatVersion(inputFilePath);
            FileHeaders.ValidateFormatVersion(inputFilePath, formatVersion, Constants.EncryptionVersion);
            long fileLength    = FileHandling.GetFileLength(inputFilePath);
            int  headersLength = FileHeaders.GetHeadersLength();

            byte[] ciphertextLength = BitConverter.GetBytes(fileLength - headersLength);
            return(Utilities.ConcatArrays(magicBytes, formatVersion, ciphertextLength));
        }
예제 #2
0
        private static void Decrypt(FileStream inputFile, FileStream outputFile, byte[] nonce, byte[] dataEncryptionKey, byte[] additionalData, int lastChunkLength)
        {
            int headersLength = FileHeaders.GetHeadersLength();

            inputFile.Seek(headersLength, SeekOrigin.Begin);
            const int offset = 0;

            byte[] ciphertextChunk = new byte[Constants.TotalChunkLength];
            while (inputFile.Read(ciphertextChunk, offset, ciphertextChunk.Length) > 0)
            {
                byte[] plaintextChunk = SecretAeadXChaCha20Poly1305.Decrypt(ciphertextChunk, nonce, dataEncryptionKey, additionalData);
                ChunkHandling.ValidateKeyCommitmentBlock(plaintextChunk);
                nonce          = Sodium.Utilities.Increment(nonce);
                additionalData = ChunkHandling.GetPreviousPoly1305Tag(ciphertextChunk);
                plaintextChunk = ChunkHandling.RemoveKeyCommitmentBlock(plaintextChunk);
                outputFile.Write(plaintextChunk, offset, plaintextChunk.Length);
            }
            outputFile.SetLength((outputFile.Length - Constants.FileChunkSize) + lastChunkLength);
            Utilities.ZeroArray(dataEncryptionKey);
        }