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);
            }
Example #2
0
 /// <summary> Encrypts the bytes with the current password and salt </summary>
 public override byte[] Encrypt(byte[] blob)
 {
     try
     {
         using (AESCryptoKey key = CreateKey())
             return(new SaltedData(Salt, key.Encrypt(blob)).ToArray());
     }
     catch (InvalidOperationException) { throw; }
     catch { throw CryptographicException(); }
 }
Example #3
0
 /// <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(); }
 }
        public void TestCopyReadWriteBytes()
        {
            byte[] ivrandom = new byte[16];
            new Random().NextBytes(ivrandom);

            using (AESCryptoKey k1 = new AESCryptoKey())
            using (AESCryptoKey k2 = AESCryptoKey.FromBytes(k1.ToArray()))
            {
                Assert.AreEqual(k1.Key, k2.Key);
                Assert.AreEqual(k1.IV, k2.IV);
            }
        }
Example #5
0
        /// <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(); }
        }
Example #6
0
        /// <summary> Encrypts the stream with the current password and salt </summary>
        public override Stream Encrypt(Stream stream)
        {
            try
            {
                Salt salt = this.Salt;
                stream.Write(salt.ToArray(), 0, salt.Length);

                AESCryptoKey key = CreateKey();
                return(new DisposingStream(key.Encrypt(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) { }
            }
        }
            //private bool _verified; /* this is a debugging aid used to ensure all messages are signed or verified */

            public Message(TransferState state, Guid transferId, RSAPublicKey key, Converter <Guid, Salt> sessionSecret)
            {
                _version    = VersionHeader;
                _state      = state;
                _transferId = transferId;
                _salt       = new Salt(Salt.Size.b256);
                _protected  = new MemoryStream();
                _payload    = new NonClosingStream(_protected);
                _hash       = new HashStream(new SHA256Managed());
                WriteHeader(_hash);
                Salt secret;

                if (!UsesSessionKey)
                {
                    // Outer encryption is straight PKI based on the remote public key
                    _payload = key.Encrypt(_payload);
                    _hash.ChangeStream(_payload);
                    // Preceed the message with a new, AES key
                    secret = new Salt(Salt.Size.b256);
                    _hash.Write(secret.ToArray(), 0, 32);
                }
                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.Encrypt(_payload);
                _hash.ChangeStream(_payload);
            }
            //private bool _verified; /* this is a debugging aid used to ensure all messages are signed or verified */

            public Message(TransferState state, Guid transferId, RSAPublicKey key, Converter<Guid, Salt> sessionSecret)
            {
                _version = VersionHeader;
                _state = state;
                _transferId = transferId;
                _salt = new Salt(Salt.Size.b256);
                _protected = new MemoryStream();
                _payload = new NonClosingStream(_protected);
                _hash = new HashStream(new SHA256Managed());
                WriteHeader(_hash);
                Salt secret;

                if (!UsesSessionKey)
                {
                    // Outer encryption is straight PKI based on the remote public key
                    _payload = key.Encrypt(_payload);
                    _hash.ChangeStream(_payload);
                    // Preceed the message with a new, AES key
                    secret = new Salt(Salt.Size.b256);
                    _hash.Write(secret.ToArray(), 0, 32);
                }
                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.Encrypt(_payload);
                _hash.ChangeStream(_payload);
            }
            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();
        }