public void Initialize(DerivedBytesProvider derivedBytesProvider, Action <Dictionary <string, byte[]> > afterHeaderRead = null) { if (derivedBytesProvider == null) { throw new ArgumentNullException(nameof(derivedBytesProvider)); } //header //FileDesignator (8 bytes) + passwordSalt (32 bytes) + hmac salt (32 bytes) + iv (32 bytes) FileHeader header = new FileHeader(); StreamRead(streamIn, header.fileDesignator); StreamRead(streamIn, header.passwordSalt); StreamRead(streamIn, header.hmacSalt); StreamRead(streamIn, header.iv); StreamRead(streamIn, header.headerAuthnDisk); afterHeaderRead?.Invoke(header.ToDictionary()); FileVersion = HelixFileVersion.GetVersion(header.fileDesignator); if (FileVersion == null) { throw new FileDesignatorException("Invalid file format, file designator not correct"); } DerivedBytes = derivedBytesProvider.GetDerivedBytes(header.passwordSalt, FileVersion.DerivedBytesIterations); byte[] headerBytes = header.GetBytesToHash(); byte[] hmacFullKey = ByteBlock.ConcatenateBytes(header.hmacSalt, DerivedBytes.Key); hmacHash = new HMACSHA256(hmacFullKey); //Validate Header HMAC byte[] headerAuthnComputed = hmacHash.ComputeHash(headerBytes); if (!ByteBlock.Equals(header.headerAuthnDisk, headerAuthnComputed)) { throw new HMACAuthenticationException("Header HMAC Authentication Failed"); } hmacTransform = new HMACDecrypt(headerAuthnComputed, hmacHash); hmacStream = new CryptoStream2(streamIn, hmacTransform, CryptoStreamMode.Read); aesTransform = Aes.Create(); aesTransform.KeySize = 256; aesTransform.BlockSize = 128; aesTransform.Mode = CipherMode.CBC; aesTransform.Padding = PaddingMode.PKCS7; aesTransform.IV = header.iv; aesTransform.Key = DerivedBytes.Key; aesStream = new CryptoStream2(hmacStream, aesTransform.CreateDecryptor(), CryptoStreamMode.Read); gzipStream = new GZipStream(aesStream, CompressionMode.Decompress, true); initialized = true; }
public static HelixFileVersion GetVersion(byte[] fileDesignator) { if (fileDesignator == null) { throw new ArgumentNullException(nameof(fileDesignator)); } return(AllVersions .Where(ver => ByteBlock.Equals(ver.FileDesignator, fileDesignator)) .FirstOrDefault()); }
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); } }