public PasswordData(string password, byte[] keyFile) { if (!string.IsNullOrEmpty(password)) { var utf8 = Encoding.UTF8.GetBytes(password); _hash = BufferEx.GetHash(utf8); } if (keyFile != null) { if (_hash != null) { var current = _hash.Length; Array.Resize(ref _hash, current + keyFile.Length); Array.Copy(keyFile, 0, _hash, current, keyFile.Length); } else { _hash = keyFile; } } if (_hash == null) { throw new InvalidOperationException( "At least password or key file must be provided"); } _hash = BufferEx.GetHash(_hash); }
public static Stream Decrypt(Stream source, Headers headers, byte[] masterKey) { byte[] easKey; using (var buffer = new MemoryStream()) { var masterSeed = headers.MasterSeed; buffer.Write(masterSeed, 0, masterSeed.Length); buffer.Write(masterKey, 0, masterKey.Length); easKey = BufferEx.GetHash(buffer.ToArray()); } var eas = new AesManaged { KeySize = 256, Key = BufferEx.Clone(easKey), IV = BufferEx.Clone(headers.EncryptionIV) }; Stream stream = new CryptoStream(source, eas.CreateDecryptor(), CryptoStreamMode.Read); if (!VerifyStartBytes(headers, stream)) { return(null); } stream = new HashedBlockStream(stream, true); return(headers.Compression == Compressions.GZip ? new GZipInputStream(stream) : stream); }
public void Verify() { Verify(HeaderFields.MasterSeed, 32, "The length of the master key seed is invalid!"); Verify(HeaderFields.TransformSeed, 32, "The length of the transform seed is invalid!"); Verify(HeaderFields.EncryptionIV, 16, "The length of the encryption IV is invalid!"); Verify(HeaderFields.StreamStartBytes, 32, "The length of the stream start bytes is invalid!"); var data = Verify(HeaderFields.CipherID, 16, "The length of the cipher engine ID is invalid!"); if (!BufferEx.Equals(_easEngineId, data)) { throw new FormatException( "Only AES encryption is supported!"); } data = Verify(HeaderFields.CompressionFlags, 4, "The length of compression format is invalid!"); var compression = (Compressions) BitConverter.ToChar(data, 0); if (compression > Compressions.GZip) { throw new FormatException( "Only no compression and GZip compression are supported!"); } }
private bool ReadHashedBlock() { if (_eof) { return(false); } _position = 0; if (_reader.ReadUInt32() != _bufferIndex) { throw new InvalidDataException(); } _bufferIndex++; var actualHash = _reader.ReadBytes(32); if ((actualHash == null) || (actualHash.Length != 32)) { throw new InvalidDataException(); } var bufferSize = _reader.ReadInt32(); if (bufferSize < 0) { throw new InvalidDataException(); } if (bufferSize == 0) { if (actualHash.Any(x => x != 0)) { throw new InvalidDataException(); } _eof = true; _buffer = new byte[0]; return(false); } _buffer = _reader.ReadBytes(bufferSize); if (_buffer == null || _buffer.Length != bufferSize) { throw new InvalidDataException(); } var expectedHash = BufferEx.GetHash(_buffer); if (!BufferEx.Equals(actualHash, expectedHash)) { throw new InvalidDataException(); } return(true); }
private static bool VerifyStartBytes( Headers headers, Stream stream) { var actual = new BinaryReader(stream) .ReadBytes(32); var expected = headers.StreamStartBytes; return(BufferEx.Equals(actual, expected)); }
public byte[] TransformKey(byte[] transformSeed, int rounds) { var block = BufferEx.Clone(_hash); var cipher = new AesEngine(); cipher.Init(true, new KeyParameter(transformSeed)); var aesEcb = SymmetricKeyAlgorithmProvider .OpenAlgorithm(SymmetricAlgorithmNames.AesEcb); var key = aesEcb.CreateSymmetricKey( CryptographicBuffer.CreateFromByteArray(transformSeed)); for (int i = 0; i < rounds; i++) { cipher.ProcessBlock(block, 0, block, 0); cipher.ProcessBlock(block, 16, block, 16); } return(BufferEx.GetHash(block)); }
public byte[] TransformKey(byte[] transformSeed, int rounds) { var block = BufferEx.Clone(_hash); var aes = new AesManaged { KeySize = 256, IV = new byte[16], Key = transformSeed, }; for (var i = 1; i <= rounds; i++) { // ECB mode is not available in Silverlight // Always use a new encrytor to emulate ECB mode. aes.CreateEncryptor().TransformBlock( block, 0, 16, block, 0); aes.CreateEncryptor().TransformBlock( block, 16, 16, block, 16); } return(BufferEx.GetHash(block)); }