예제 #1
0
        public HelixFileEncryptor(Stream streamOut, DerivedBytesProvider derivedBytesProvider, HelixFileVersion fileVersion = null)
        {
            if (streamOut == null)
            {
                throw new ArgumentNullException(nameof(streamOut));
            }
            if (!streamOut.CanWrite)
            {
                throw new ArgumentException("streamOut must be writable", nameof(streamOut));
            }
            if (derivedBytesProvider == null)
            {
                throw new ArgumentNullException(nameof(derivedBytesProvider));
            }

            this.FileVersion = fileVersion ?? HelixFileVersion.Default;

            this.StreamOut    = streamOut;
            this.DerivedBytes = derivedBytesProvider.GetDerivedBytes(FileVersion.DerivedBytesIterations);
        }
예제 #2
0
        public DerivedBytes GetDerivedBytes(byte[] salt, int derivedBytesIterations)
        {
            if (derivedBytesIterations < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(derivedBytesIterations));
            }
            if (salt == null)
            {
                throw new ArgumentOutOfRangeException(nameof(salt));
            }

            if (ByteBlock.Equals(salt, lastDerivedBytes?.Salt))
            {
                return(lastDerivedBytes);
            }

            using (Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(m_password, salt, derivedBytesIterations))
            {
                lastDerivedBytes = new DerivedBytes(deriveBytes.GetBytes(256 / 8), deriveBytes.Salt, derivedBytesIterations);
                return(lastDerivedBytes);
            }
        }
예제 #3
0
 public MultiBlockEncryptor(Stream streamOut, DerivedBytes derivedBytes, HelixFileVersion fileVersion)
     : base(new AuthenticatedEncryptor(streamOut, derivedBytes, fileVersion))
 {
 }
예제 #4
0
        public AuthenticatedEncryptor(Stream streamOut, DerivedBytes derivedBytes, HelixFileVersion hxVersion, byte[] hmacSalt = null, byte[] iv = null)
        {
            if (derivedBytes == null)
            {
                throw new ArgumentNullException(nameof(derivedBytes));
            }
            if (hxVersion == null)
            {
                throw new ArgumentNullException(nameof(hxVersion));
            }
            if (hmacSalt != null && hmacSalt.Length != HelixConsts.HMACSaltSize)
            {
                throw new ArgumentOutOfRangeException(nameof(hmacSalt));
            }
            if (iv != null && iv.Length != HelixConsts.IVSize)
            {
                throw new ArgumentOutOfRangeException(nameof(iv));
            }

            using (var random = RandomNumberGenerator.Create())
            {
                if (hmacSalt == null)
                {
                    hmacSalt = new byte[HelixConsts.HMACSaltSize];
                    random.GetBytes(hmacSalt);
                }

                if (iv == null)
                {
                    iv = new byte[HelixConsts.IVSize];
                    random.GetBytes(iv);
                }
            }

            FileHeader header = new FileHeader
            {
                fileDesignator = hxVersion.FileDesignator,
                passwordSalt   = derivedBytes.Salt,
                hmacSalt       = hmacSalt,
                iv             = iv,
            };

            byte[] hmacFullKey = ByteBlock.ConcatenateBytes(hmacSalt, derivedBytes.Key);


            this.streamOut = streamOut ?? throw new ArgumentNullException(nameof(streamOut));

            byte[] bytesToHash = header.GetBytesToHash();
            streamOut.Write(bytesToHash, 0, bytesToHash.Length);

            hmacHash = new HMACSHA256(hmacFullKey);

            header.headerAuthnDisk = hmacHash.ComputeHash(header.GetBytesToHash());
            streamOut.Write(header.headerAuthnDisk, 0, header.headerAuthnDisk.Length);

            hmacTransform = new HMACEncrypt(header.headerAuthnDisk, hmacHash);
            hmacStream    = new CryptoStream(streamOut, hmacTransform, CryptoStreamMode.Write);


            aesTransform           = Aes.Create();
            aesTransform.KeySize   = 256;
            aesTransform.BlockSize = 128;
            aesTransform.Mode      = CipherMode.CBC;
            aesTransform.Padding   = PaddingMode.PKCS7;
            aesTransform.IV        = iv;
            aesTransform.Key       = derivedBytes.Key;

            aesStream = new CryptoStream(hmacStream, aesTransform.CreateEncryptor(), CryptoStreamMode.Write);

            gzipStream = new GZipStream(aesStream, CompressionMode.Compress, true);
        }