Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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!");
            }
        }
Пример #4
0
        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);
        }
Пример #5
0
        private static bool VerifyStartBytes(
            Headers headers, Stream stream)
        {
            var actual = new BinaryReader(stream)
                         .ReadBytes(32);
            var expected = headers.StreamStartBytes;

            return(BufferEx.Equals(actual, expected));
        }
Пример #6
0
        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));
        }
Пример #7
0
        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));
        }