Beispiel #1
0
        internal void _Decrypt(Stream inputStream, Stream outputStream, byte[] password)
        {
            var info = new byte[HashLengthSize + SaltLengthSize + EncryptedLengthSize];
            inputStream.Read(info, 0, info.Length);

            var hashLength = BitConverter.ToInt32(info, 0);
            var saltLength = BitConverter.ToInt32(info, HashLengthSize);
            var encryptedLength = BitConverter.ToInt64(info, HashLengthSize + SaltLengthSize);

            byte[] salt = new byte[saltLength], hash = new byte[hashLength];
            inputStream.Read(hash,0, hashLength);
            inputStream.Read(salt, 0, saltLength);

            using (var rfc2898 = new Rfc2898DeriveBytes(password, salt, DefaultIteration))
            using (var algorithm = GetSymmetricAlgorithm())
            {
                algorithm.KeySize = DefaultKeySize;
                algorithm.BlockSize = DefaultBlockSize;

                var key = rfc2898.GetBytes(DefaultKeySize / 8);
                var iv = rfc2898.GetBytes(DefaultBlockSize / 8);

                using (var transform = algorithm.CreateDecryptor(key, iv))
                using (var hasher = IncrementalHash.CreateHMAC(DefaultHashAlgorithm, password))
                using (var crytoStream = new CryptoStream(outputStream, transform, CryptoStreamMode.Write))
                {
                    foreach (var bytes in inputStream.ReadByChunk(Config.DefaultChunkSize, encryptedLength))
                    {
                        hasher.AppendData(bytes);
                        crytoStream.Write(bytes, 0, bytes.Length);
                    }

                    if (!hash.SequenceEqual(hasher.GetHashAndReset()))
                        throw new Exception("HMAC value is not correct");
                }
            }
        }
Beispiel #2
0
        internal void _EncryptThenMac(Stream inputStream, Stream outputStream, byte[] password, byte[] salt)
        {
            using (var rfc2898 = new Rfc2898DeriveBytes(password, salt, DefaultIteration))
            using (var algorithm = GetSymmetricAlgorithm())
            {
                algorithm.KeySize = DefaultKeySize;
                algorithm.BlockSize = DefaultBlockSize;

                var key = rfc2898.GetBytes(DefaultKeySize / 8);
                var iv = rfc2898.GetBytes(DefaultBlockSize / 8);

                long encryptedLength = 0;

                using (var transform = algorithm.CreateEncryptor(key, iv))
                using (var hasher = IncrementalHash.CreateHMAC(DefaultHashAlgorithm, password))
                using (var delegateStream = new DelegateStream(outputStream, null, (buffer, offset, count) => { encryptedLength += buffer.Length; hasher.AppendData(buffer); }))
                {
                    var hash = hasher.GetHashAndReset();
                    outputStream.Write(BitConverter.GetBytes(hash.Length), 0, HashLengthSize);
                    outputStream.Write(BitConverter.GetBytes(salt.Length), 0, SaltLengthSize);
                    outputStream.Write(BitConverter.GetBytes(encryptedLength), 0, EncryptedLengthSize);
                    outputStream.Write(hash, 0, hash.Length);
                    outputStream.Write(salt, 0, salt.Length);

                    using (var crytoStream = new CryptoStream(delegateStream, transform, CryptoStreamMode.Write))
                    {
                        foreach (var bytes in inputStream.ReadByChunk())
                            crytoStream.Write(bytes, 0, bytes.Length);
                    }

                    outputStream.Seek(HashLengthSize + SaltLengthSize, SeekOrigin.Begin);
                    outputStream.Write(BitConverter.GetBytes(encryptedLength), 0, EncryptedLengthSize);
                    outputStream.Write(hasher.GetHashAndReset(), 0, hash.Length);
                }
            }
        }