Example #1
0
        public void EnhancedMemoryStream_Byte()
        {
            var es = new EnhancedMemoryStream();

            es.WriteByte(77);
            es.WriteByte(99);

            es.Seek(0, SeekOrigin.Begin);

            Assert.AreEqual(77, es.ReadByte());
            Assert.AreEqual(99, es.ReadByte());
        }
Example #2
0
        public void SecureFile_Stream_Validate()
        {
            string privateKey              = AsymmetricCrypto.CreatePrivateKey(CryptoAlgorithm.RSA, 1024);
            string publicKey               = AsymmetricCrypto.GetPublicKey(CryptoAlgorithm.RSA, privateKey);
            EnhancedMemoryStream original  = new EnhancedMemoryStream();
            EnhancedMemoryStream encrypted = new EnhancedMemoryStream();
            SecureFile           secure    = null;
            byte b;

            for (int i = 0; i < 100; i++)
            {
                original.WriteByte((byte)i);
            }

            secure            = new SecureFile(original, SecureFileMode.Encrypt, publicKey);
            original.Position = 0;
            secure.EncryptTo(encrypted, CryptoAlgorithm.AES, 256);
            secure.Close();
            secure = null;

            encrypted.Position = 0;
            Assert.IsTrue(SecureFile.Validate(encrypted, privateKey));

            encrypted.Position = encrypted.Length - 1;
            b = (byte)encrypted.ReadByte();
            encrypted.Position = encrypted.Length - 1;
            encrypted.WriteByte((byte)(~b));

            encrypted.Position = 0;
            Assert.IsFalse(SecureFile.Validate(encrypted, privateKey));
        }
Example #3
0
        public void SecureFile_Stream_LargeContent()
        {
            string privateKey              = AsymmetricCrypto.CreatePrivateKey(CryptoAlgorithm.RSA, 1024);
            string publicKey               = AsymmetricCrypto.GetPublicKey(CryptoAlgorithm.RSA, privateKey);
            EnhancedMemoryStream original  = new EnhancedMemoryStream();
            EnhancedMemoryStream encrypted = new EnhancedMemoryStream();
            EnhancedMemoryStream decrypted = new EnhancedMemoryStream();
            SecureFile           secure    = null;

            for (int i = 0; i < 128000; i++)
            {
                original.WriteByte((byte)i);
            }

            secure            = new SecureFile(original, SecureFileMode.Encrypt, publicKey);
            original.Position = 0;
            secure.EncryptTo(encrypted, CryptoAlgorithm.AES, 256);
            secure.Close();
            secure = null;

            encrypted.Position = 0;
            secure             = new SecureFile(encrypted, SecureFileMode.Decrypt, privateKey);
            secure.DecryptTo(decrypted);
            secure.Close();
            secure = null;

            original.Position  = 0;
            encrypted.Position = 0;
            CollectionAssert.AreNotEqual(original.ReadBytesToEnd(), encrypted.ReadBytesToEnd());

            original.Position  = 0;
            decrypted.Position = 0;
            CollectionAssert.AreEqual(original.ReadBytesToEnd(), decrypted.ReadBytesToEnd());
        }
Example #4
0
        /// <summary>
        /// Serializes and encrypts the message into a byte array.
        /// </summary>
        /// <param name="sharedKey">The shared encryption key.</param>
        /// <returns>The serialized message.</returns>
        public byte[] ToArray(SymmetricKey sharedKey)
        {
            using (var ms = new EnhancedMemoryStream(2048))
            {
                var addressBytes = SourceAddress.GetAddressBytes();

                if (addressBytes.Length != 4)
                {
                    throw new InvalidOperationException("UdpBroadcastMessage supports only IPv4 address.");
                }

                ms.WriteInt32Le(Magic);
                ms.WriteInt64Le(TimeStampUtc.Ticks);
                ms.WriteBytesNoLen(SourceAddress.GetAddressBytes());
                ms.WriteByte((byte)MessageType);
                ms.WriteByte((byte)BroadcastGroup);
                ms.WriteBytes16(Payload);
                ms.WriteBytesNoLen(Crypto.GetSalt4());

                return(Crypto.Encrypt(ms.ToArray(), sharedKey));
            }
        }
Example #5
0
        public void Package_HashVerify()
        {
            Package              package;
            EnhancedBlockStream  bs = new EnhancedBlockStream();
            EnhancedMemoryStream es = new EnhancedMemoryStream();
            PackageEntry         entry;

            byte[] buf;
            byte   v;

            buf = new byte[37000];
            for (int i = 0; i < buf.Length; i++)
            {
                buf[i] = (byte)i;
            }

            //-------------------------

            package = new Package();
            package.Create(es);

            bs.WriteBytes32(buf);
            bs.Position = 0;

            entry = package.AddFile("/Foo/Bar/Test1.dat", bs, (int)bs.Length);
            Assert.IsTrue(bs.Eof);
            Assert.IsTrue(entry.IsFile);
            Assert.IsTrue(package["/Foo"].IsFolder);
            Assert.IsTrue(package["/Foo/Bar"].IsFolder);
            Assert.IsTrue(package["/Foo/Bar/Test1.dat"].IsFile);

            package.Close(true);

            es.Position = es.Length / 2;  // Corrupt a byte in the middle of the stream
                                          // to verify that the MD5 hash comparision
                                          // catches it.
            v = (byte)es.ReadByte();
            es.Seek(-1, SeekOrigin.Current);
            es.WriteByte((byte)~v);

            es.Position = 0;

            try
            {
                package = new Package(es);
                Assert.Fail();
            }
            catch (PackageException)
            {
            }
        }
Example #6
0
        private EnhancedMemoryStream CreateStream(int cb)
        {
            EnhancedMemoryStream ms;

            ms = new EnhancedMemoryStream();

            for (int i = 0; i < cb; i++)
            {
                ms.WriteByte((byte)i);
            }

            ms.Position = 0;
            return(ms);
        }
Example #7
0
        /// <summary>
        /// Serializes and encrypts the message into a byte array.
        /// </summary>
        /// <param name="sharedKey">The shared encryption key.</param>
        /// <returns>The serialized message.</returns>
        public byte[] ToArray(SymmetricKey sharedKey)
        {
            if (this.HostEntry == null)
            {
                throw new InvalidOperationException("HostEntry property cannot be null.");
            }

            using (var ms = new EnhancedMemoryStream(2048))
            {
                ms.WriteInt32Le(Magic);
                ms.WriteByte((byte)FormatVer);
                ms.WriteInt64Le(TimeStampUtc.Ticks);
                ms.WriteInt32Le((int)Flags);
                ms.WriteString16(this.HostEntry.ToString());
                ms.WriteBytesNoLen(Crypto.GetSalt4());

                return(Crypto.Encrypt(ms.ToArray(), sharedKey));
            }
        }
Example #8
0
        public void SecureFile_Stream_BadHash()
        {
            string privateKey              = AsymmetricCrypto.CreatePrivateKey(CryptoAlgorithm.RSA, 1024);
            string publicKey               = AsymmetricCrypto.GetPublicKey(CryptoAlgorithm.RSA, privateKey);
            EnhancedMemoryStream original  = new EnhancedMemoryStream();
            EnhancedMemoryStream encrypted = new EnhancedMemoryStream();
            EnhancedMemoryStream decrypted = new EnhancedMemoryStream();
            SecureFile           secure    = null;
            byte b;

            for (int i = 0; i < 100; i++)
            {
                original.WriteByte((byte)i);
            }

            secure            = new SecureFile(original, SecureFileMode.Encrypt, publicKey);
            original.Position = 0;
            secure.EncryptTo(encrypted, CryptoAlgorithm.AES, 256);
            secure.Close();
            secure = null;

            // Munge the last byte of the hash digest and then
            // confirm the this is detected

            encrypted.Position = encrypted.Length - 1;
            b = (byte)encrypted.ReadByte();
            encrypted.Position = encrypted.Length - 1;
            encrypted.WriteByte((byte)(~b));

            encrypted.Position = 0;
            secure             = new SecureFile(encrypted, SecureFileMode.Decrypt, privateKey);

            try
            {
                secure.DecryptTo(decrypted);
                Assert.Fail("Corrupt hash digest not detected.");
            }
            catch
            {
                // Expecting an exception
            }
        }
Example #9
0
        /// <summary>
        /// Performs a secure symmetric encryption including cryptographic salt, padding, and
        /// data validation.
        /// </summary>
        /// <param name="symmetricKey">The symmetric algorithm arguments.</param>
        /// <param name="plainText">The unencrypted data.</param>
        /// <param name="paddedSize">Specifies the minimum padded size of the encrypted content.</param>
        /// <returns>The encrypted result.</returns>
        public static byte[] Encrypt(SymmetricKey symmetricKey, byte[] plainText, int paddedSize)
        {
            EnhancedMemoryStream output    = new EnhancedMemoryStream(Math.Max(plainText.Length, paddedSize) + 512);
            EnhancedMemoryStream ms        = new EnhancedMemoryStream(512);
            BlockEncryptor       encryptor = new BlockEncryptor(symmetricKey);

            try
            {
                // Write header fields

                output.WriteInt32(Magic);
                output.WriteInt32(0);

                // Write encrypted contents

                ms.WriteInt32(Magic);
                ms.WriteBytesNoLen(Crypto.GetSalt8());
                ms.WriteBytes32(plainText);

                for (int i = plainText.Length; i < paddedSize; i++)
                {
                    ms.WriteByte((byte)i);     // Padding bytes
                }
                output.WriteBytes32(encryptor.Encrypt(ms.ToArray()));

                // That's it, we're done.

                return(output.ToArray());
            }
            finally
            {
                if (encryptor != null)
                {
                    encryptor.Dispose();
                }

                output.Close();
                ms.Close();
            }
        }
Example #10
0
        public void SecureFile_Stream_GetPublicKey()
        {
            string privateKey              = AsymmetricCrypto.CreatePrivateKey(CryptoAlgorithm.RSA, 1024);
            string publicKey               = AsymmetricCrypto.GetPublicKey(CryptoAlgorithm.RSA, privateKey);
            EnhancedMemoryStream original  = new EnhancedMemoryStream();
            EnhancedMemoryStream encrypted = new EnhancedMemoryStream();
            SecureFile           secure    = null;

            for (int i = 0; i < 100; i++)
            {
                original.WriteByte((byte)i);
            }

            // Verify that the public key is saved when requested (the default)

            secure = new SecureFile(original, SecureFileMode.Encrypt, publicKey);
            Assert.IsTrue(secure.SavePublicKey);
            Assert.AreEqual(publicKey, secure.PublicKey);

            original.Position = 0;
            secure.EncryptTo(encrypted, CryptoAlgorithm.AES, 256);
            secure.Close();
            secure = null;

            encrypted.Position = 0;
            Assert.AreEqual(publicKey, SecureFile.GetPublicKey(encrypted));

            // Verify that the public key is not saved if SavePublicKey=false

            encrypted.SetLength(0);
            secure = new SecureFile(original, SecureFileMode.Encrypt, publicKey);
            secure.SavePublicKey = false;
            original.Position    = 0;
            secure.EncryptTo(encrypted, CryptoAlgorithm.AES, 256);
            secure.Close();
            secure = null;

            encrypted.Position = 0;
            Assert.IsNull(SecureFile.GetPublicKey(encrypted));
        }
Example #11
0
        /// <summary>
        /// Encrypts a byte array using a combination of an asymmetric RSA key and the
        /// specified symmetric encryption algorithm and a one-time key generated by
        /// the method.
        /// </summary>
        /// <param name="rsaKey">The encrypting RSA key as XML or as a secure key container name.</param>
        /// <param name="plainText">The data to be encrypted.</param>
        /// <param name="algorithm">The symmetric encryption algorithm name.</param>
        /// <param name="keySize">The one-time symmetric key size to generate in bits.</param>
        /// <param name="paddedSize">Specifies the minimum padded size of the encrypted content.</param>
        /// <param name="symmetricKey">Returns as the symmetric encryption algorithm arguments.</param>
        /// <returns>The encrypted result.</returns>
        /// <remarks>
        /// <para>
        /// Note that applications should take some care to ensure that the <paramref name="symmetricKey" />
        /// value return is disposed so that the symmetric encryption key will be cleared.
        /// </para>
        /// <para>
        /// The current supported cross platform encryption algorithms
        /// are: "DES", "RC2", "TripleDES", and "AES" (Rijndael).
        /// </para>
        /// </remarks>
        /// <exception cref="ArgumentException">Thrown if the requested encryption algorithm is unknown.</exception>
        public static byte[] Encrypt(string rsaKey, byte[] plainText, string algorithm, int keySize, int paddedSize,
                                     out SymmetricKey symmetricKey)
        {
            EnhancedMemoryStream output    = new EnhancedMemoryStream(Math.Max(plainText.Length, paddedSize) + 512);
            EnhancedMemoryStream ms        = new EnhancedMemoryStream(512);
            BlockEncryptor       encryptor = null;

            byte[] symKey;
            byte[] symIV;

            Crypto.GenerateSymmetricKey(algorithm, keySize, out symKey, out symIV);

            encryptor    = new BlockEncryptor(algorithm, symKey, symIV);
            symmetricKey = new SymmetricKey(algorithm, (byte[])symKey.Clone(), (byte[])symIV.Clone());

            try
            {
                // Write header fields

                output.WriteInt32(Magic);
                output.WriteInt32(0);

                // Write encryption Info

                ms.WriteString16(algorithm);
                ms.WriteBytes16(symKey);
                ms.WriteBytes16(symIV);
                ms.WriteBytesNoLen(Crypto.GetSalt8());
                output.WriteBytes16(AsymmetricCrypto.Encrypt(CryptoAlgorithm.RSA, rsaKey, ms.ToArray()));

                // Write encrypted contents

                ms.SetLength(0);
                ms.WriteInt32(Magic);
                ms.WriteBytesNoLen(Crypto.GetSalt8());
                ms.WriteBytes32(plainText);

                for (int i = plainText.Length; i < paddedSize; i++)
                {
                    ms.WriteByte((byte)i);     // Padding bytes
                }
                output.WriteBytes32(encryptor.Encrypt(ms.ToArray()));

                // That's it, we're done.

                return(output.ToArray());
            }
            finally
            {
                if (symKey != null)
                {
                    Array.Clear(symKey, 0, symKey.Length);
                }

                if (symIV != null)
                {
                    Array.Clear(symIV, 0, symIV.Length);
                }

                if (encryptor != null)
                {
                    encryptor.Dispose();
                }

                output.Close();
                ms.Close();
            }
        }
Example #12
0
        public void SecureFile_File_KeyChain()
        {
            string encryptName            = Path.GetTempFileName();
            string privateKey             = AsymmetricCrypto.CreatePrivateKey(CryptoAlgorithm.RSA, 1024);
            string publicKey              = AsymmetricCrypto.GetPublicKey(CryptoAlgorithm.RSA, privateKey);
            EnhancedMemoryStream original = new EnhancedMemoryStream();
            SecureFile           secure   = null;

            try
            {
                for (int i = 0; i < 100; i++)
                {
                    original.WriteByte((byte)i);
                }

                // Verify that SecureFile can find the correct private key in the key chain.

                secure = new SecureFile(original, SecureFileMode.Encrypt, publicKey);
                Assert.IsTrue(secure.SavePublicKey);
                Assert.AreEqual(publicKey, secure.PublicKey);

                original.Position = 0;
                secure.EncryptTo(encryptName, CryptoAlgorithm.AES, 256);
                secure.Close();
                secure = null;

                var keyChain  = new KeyChain();
                var decrypted = new EnhancedMemoryStream();

                keyChain.Add(privateKey);

                secure = new SecureFile(encryptName, keyChain);
                secure.DecryptTo(decrypted);
                secure.Close();
                secure = null;

                CollectionAssert.AreEqual(original.ToArray(), decrypted.ToArray());

                // Verify that SecureFile throws a CryptographicException if the
                // key is not present in the chain.

                keyChain.Clear();

                try
                {
                    secure = new SecureFile(encryptName, keyChain);
                    secure.DecryptTo(decrypted);
                    Assert.Fail("Expecting a CryptographicException");
                }
                catch (CryptographicException)
                {
                    // Expecting this
                }
                finally
                {
                    if (secure != null)
                    {
                        secure.Close();
                        secure = null;
                    }
                }

                // Verify that SecureFile throws a CryptographicException if the
                // public key was not saved to the file.

                keyChain.Add(privateKey);

                secure = new SecureFile(original, SecureFileMode.Encrypt, publicKey);
                secure.SavePublicKey = false;

                original.Position = 0;

                secure.EncryptTo(encryptName, CryptoAlgorithm.AES, 256);
                secure.Close();
                secure = null;

                try
                {
                    secure = new SecureFile(encryptName, keyChain);
                    secure.DecryptTo(decrypted);
                    Assert.Fail("Expecting a CryptographicException");
                }
                catch (CryptographicException)
                {
                    // Expecting this
                }
                finally
                {
                    if (secure != null)
                    {
                        secure.Close();
                        secure = null;
                    }
                }
            }
            finally
            {
                System.IO.File.Delete(encryptName);
            }
        }