public Message(Stream input, RSAPrivateKey key, Converter <Guid, Salt> sessionSecret)
            {
                (_protected = new MemoryStream(0)).Dispose();
                _hash    = new HashStream(new SHA256Managed(), input);
                _payload = input;

                ReadHeader(_hash, out _version, out _state, out _transferId, out _salt);

                Salt secret;

                if (!UsesSessionKey)
                {
                    // Begin private key decryption
                    _payload = key.Decrypt(input);
                    _hash.ChangeStream(_payload);
                    // Decrypt the aes key used in this package
                    byte[] keybits = IOStream.Read(_hash, 32);
                    secret = Salt.FromBytes(keybits);
                }
                else
                {
                    secret = sessionSecret(_transferId);
                    Check.IsEqual(32, Check.NotNull(secret).Length);
                }

                AESCryptoKey sessionKey = new AESCryptoKey(
                    // Prefix the key with the message's salt and compute a SHA256 hash to be used as the key
                    Hash.SHA256(_salt.GetData(secret.ToArray()).ToStream()).ToArray(),
                    // Compute an IV for this aes key and salt combination
                    IV(secret, _salt)
                    );

                _payload = sessionKey.Decrypt(_payload);
                _hash.ChangeStream(_payload);
            }
 /// <summary> Decrypts the bytes with the current password and salt </summary>
 public byte[] Decrypt(byte[] blob, Salt.Size szSaltSize)
 {
     try
     {
         using (SaltedData data = new SaltedData(blob, szSaltSize))
             using (AESCryptoKey key = CreateKey(data.Salt))
                 return(key.Decrypt(data.GetDataBytes()));
     }
     catch (InvalidOperationException) { throw; }
     catch { throw CryptographicException(); }
 }
        /// <summary> Decrypts the stream with the current password and salt </summary>
        public Stream Decrypt(Stream stream, Salt.Size szSaltSize)
        {
            try
            {
                Salt salt = new Salt(IOStream.Read(stream, (int)szSaltSize / 8), false);

                AESCryptoKey key = CreateKey(salt);
                return(new DisposingStream(key.Decrypt(stream))
                       .WithDisposeOf(key));
            }
            catch (InvalidOperationException) { throw; }
            catch { throw CryptographicException(); }
        }
        public void TestCopyKeyAndIV()
        {
            byte[] ivrandom = new byte[16];
            new Random().NextBytes(ivrandom);

            using (AESCryptoKey k1 = new AESCryptoKey())
            using (AESCryptoKey k2 = new AESCryptoKey(k1.Key, k1.IV))
            using (AESCryptoKey kBadIv = new AESCryptoKey(k1.Key, ivrandom))
            {
                Assert.AreEqual(k1.Key, k2.Key);
                Assert.AreEqual(k1.IV, k2.IV);
                Assert.AreEqual("test", k2.Decrypt(k1.Encrypt("test")));

                Assert.AreEqual(k1.Key, kBadIv.Key);
                Assert.AreNotEqual(k1.IV, kBadIv.IV);
                try
                {   //one of two possible outcomes, junk or exception
                    Assert.AreNotEqual("test", kBadIv.Decrypt(k1.Encrypt("test")));
                }
                catch (System.Security.Cryptography.CryptographicException) { }
            }
        }
            public Message(Stream input, RSAPrivateKey key, Converter<Guid, Salt> sessionSecret)
            {
                (_protected = new MemoryStream(0)).Dispose();
                _hash = new HashStream(new SHA256Managed(), input);
                _payload = input;

                ReadHeader(_hash, out _version, out _state, out _transferId, out _salt);
                
                Salt secret;
                if (!UsesSessionKey)
                {
                    // Begin private key decryption
                    _payload = key.Decrypt(input);
                    _hash.ChangeStream(_payload);
                    // Decrypt the aes key used in this package
                    byte[] keybits = IOStream.Read(_hash, 32);
                    secret = Salt.FromBytes(keybits);
                }
                else
                {
                    secret = sessionSecret(_transferId);
                    Check.IsEqual(32, Check.NotNull(secret).Length);
                }

                AESCryptoKey sessionKey = new AESCryptoKey(
                    // Prefix the key with the message's salt and compute a SHA256 hash to be used as the key
                    Hash.SHA256(_salt.GetData(secret.ToArray()).ToStream()).ToArray(),
                    // Compute an IV for this aes key and salt combination
                    IV(secret, _salt)
                );
                
                _payload = sessionKey.Decrypt(_payload);
                _hash.ChangeStream(_payload);
            }
 public void TestSimpleEncryptDecrypt()
 {
     using (AESCryptoKey k1 = new AESCryptoKey())
     {
         byte[] test = new byte[240];
         byte[] cypher1 = k1.Encrypt(test);
         byte[] cypher2 = k1.Encrypt(test);
         Assert.AreEqual(cypher1, cypher2);
         Assert.AreEqual(test, k1.Decrypt(cypher1));
     }
 }
        public void TestDisposal()
        {
            string test;
            CryptoKey key = new AESCryptoKey();
            test = key.Encrypt("Test");
            key.Dispose();

            key.Decrypt(test);
            Assert.Fail();
        }