Beispiel #1
0
        public void TestEmptyMemoryStream()
        {
            byte[] input = SecureRandomizer.GetRandomBytes(0);
            byte[] encrypted;
            using (var inputStream = new MemoryStream(input))
            {
                using (var outputStream = new MemoryStream())
                {
                    _symmetric.EncryptStream(inputStream, outputStream, _key);
                    encrypted = outputStream.ToArray();
                }
            }

            Assert.IsTrue(encrypted.Length >= 32, "encrypted.Length");

            byte[] decrypted;
            using (var inputStream = new MemoryStream(encrypted))
            {
                using (var outputStream = new MemoryStream())
                {
                    _symmetric.DecryptStream(inputStream, outputStream, _key);
                    decrypted = outputStream.ToArray();
                }
            }
            Assert.AreEqual(0, decrypted.Length, "decrypted.Length");
        }
Beispiel #2
0
        public void TestMemoryStream()
        {
            byte[] input = SecureRandomizer.GetRandomBytes(15000);
            byte[] encrypted;
            using (var inputStream = new MemoryStream(input))
            {
                using (var outputStream = new MemoryStream())
                {
                    _symmetric.EncryptStream(inputStream, outputStream, _key);
                    encrypted = outputStream.ToArray();
                }
            }

            Assert.IsTrue(encrypted.Length > 15000, "encrypted.Length");

            byte[] decrypted;
            using (var inputStream = new MemoryStream(encrypted))
            {
                using (var outputStream = new MemoryStream())
                {
                    _symmetric.DecryptStream(inputStream, outputStream, _key);
                    decrypted = outputStream.ToArray();
                }
            }
            Assert.IsTrue(input.SequenceEqual(decrypted), "input does not match decrypted");
        }
Beispiel #3
0
        public void TestThreadSafety()
        {
            var hashset = new HashSet <string>();

            ThreadStart action = () =>
            {
                for (int i = 0; i < 50000; ++i)
                {
                    byte[] bytes = SecureRandomizer.GetRandomBytes(32);
                    lock (hashset)
                    {
                        hashset.Add(Convert.ToBase64String(bytes));
                    }
                }
            };

            var threads = new Thread[10];

            for (int i = 0; i < threads.Length; ++i)
            {
                var thread = new Thread(action);
                threads[i] = thread;
                thread.Start();
            }
            foreach (var t in threads)
            {
                while (t.IsAlive)
                {
                }
            }

            Assert.AreEqual(500000, hashset.Count, "Number of unique arrays");
        }
Beispiel #4
0
        public void TestNoMoreThan16OfTheSameByte()
        {
            var bytes = new byte[32];

            for (int i = 0; i < 500000; ++i)
            {
                bytes = SecureRandomizer.GetRandomBytes(bytes.Length);
                var countByValue = new Dictionary <byte, int>();
                foreach (byte b in bytes)
                {
                    if (!countByValue.ContainsKey(b))
                    {
                        countByValue[b] = 1;
                    }
                    else
                    {
                        ++countByValue[b];
                    }
                }
                foreach (var kvp in countByValue)
                {
                    if (kvp.Value >= 16)
                    {
                        Assert.Fail("Value {0} appeared 16 or more times", kvp.Key);
                    }
                }
            }
        }
Beispiel #5
0
        public void TestAllPositionsContainsAllBytes()
        {
            var byteValuesByPosition = new HashSet <byte> [32];

            for (int i = 0; i < 32; ++i)
            {
                byteValuesByPosition[i] = new HashSet <byte>();
            }

            var bytes = new byte[32];

            for (int i = 0; i < 500000; ++i)
            {
                bytes = SecureRandomizer.GetRandomBytes(bytes.Length);

                for (int j = 0; j < 32; ++j)
                {
                    byteValuesByPosition[j].Add(bytes[j]);
                }
            }

            for (int i = 0; i < 32; ++i)
            {
                Assert.AreEqual(256, byteValuesByPosition[i].Count, "Position {0} does not contain all 256 possible values", i);
            }
        }
Beispiel #6
0
 public void TestBytesLarge()
 {
     byte[] input     = SecureRandomizer.GetRandomBytes(250000);
     byte[] encrypted = _symmetric.EncryptBytes(input, _key);
     Assert.IsTrue(encrypted.Length > 250000, "encrypted.Length");
     byte[] decrypted = _symmetric.DecryptBytes(encrypted, _key);
     Assert.IsTrue(input.SequenceEqual(decrypted), "input does not match decrypted");
 }
        public void TestBytesMedium()
        {
            byte[] input     = SecureRandomizer.GetRandomBytes(3200);
            byte[] encrypted = _symmetric.EncryptBytes(input, _passphrase);
            Assert.IsTrue(encrypted.Length > 3200, "encrypted.Length");

            byte[] decrypted = _symmetric.DecryptBytes(encrypted, _passphrase);
            Assert.IsTrue(input.SequenceEqual(decrypted), "input does not match decrypted");
        }
Beispiel #8
0
 public void TestBytesSmall()
 {
     byte[] input     = SecureRandomizer.GetRandomBytes(100);
     byte[] encrypted = _symmetric.EncryptBytes(input, _key);
     Assert.IsTrue(encrypted.Length > 100, "encrypted.Length");
     byte[] decrypted = _symmetric.DecryptBytes(encrypted, _key);
     Assert.IsTrue(input.SequenceEqual(decrypted), string.Format("{0} | {1}",
                                                                 Convert.ToBase64String(input), Convert.ToBase64String(decrypted)));
 }
Beispiel #9
0
        public void TestUnicodeString()
        {
            string input     = Convert.ToBase64String(SecureRandomizer.GetRandomBytes(100)) + "\u01e2\u01f0\u020e\u0229";
            string encrypted = _symmetric.EncryptString(input, _key).AsBase64();

            Assert.IsTrue(encrypted.Length > 100, "encrypted.Length");
            string decrypted = _symmetric.DecryptBase64(encrypted, _key).AsString();

            Assert.AreEqual(input, decrypted, string.Format("{0} | {1}", input, decrypted));
        }
Beispiel #10
0
        public void TestSameInputProducesDifferentOutput()
        {
            var inputBytes        = SecureRandomizer.GetRandomBytes(1024);
            var encryptedAsBase64 = new HashSet <string>();

            for (int i = 0; i < 20; ++i)
            {
                encryptedAsBase64.Add(Convert.ToBase64String(_symmetric.EncryptBytes(inputBytes, _key)));
            }
            Assert.AreEqual(20, encryptedAsBase64.Count, "Should be 100 distinct values");
        }
Beispiel #11
0
        public void TestFileStream()
        {
            string originalFileName = GetTempFileName();

            using (var tempFileStream = File.Create(originalFileName))
            {
                for (int i = 0; i < 100; ++i)
                {
                    tempFileStream.Write(SecureRandomizer.GetRandomBytes(1024), 0, 1024);
                }
            }

            string encryptedFileName = GetTempFileName();

            using (var inputStream = File.Open(originalFileName, FileMode.Open, FileAccess.Read, FileShare.None))
            {
                using (var outputStream = File.Create(encryptedFileName))
                {
                    _symmetric.EncryptStream(inputStream, outputStream, _key);
                }
            }

            string decryptedFileName = GetTempFileName();

            using (var inputStream = File.Open(encryptedFileName, FileMode.Open, FileAccess.Read, FileShare.None))
            {
                using (var outputStream = File.Create(decryptedFileName))
                {
                    _symmetric.DecryptStream(inputStream, outputStream, _key);
                }
            }

            var originalFile  = new FileInfo(originalFileName);
            var encryptedFile = new FileInfo(encryptedFileName);
            var decryptedFile = new FileInfo(decryptedFileName);

            Assert.IsTrue(encryptedFile.Length > originalFile.Length, "Encrypted file should be larger than original.");
            Assert.AreEqual(originalFile.Length, decryptedFile.Length, "Original file should be the same size as original.");

            var buffer1 = new byte[8096];
            var buffer2 = new byte[8096];

            using (var originalStream = File.Open(originalFileName, FileMode.Open, FileAccess.Read, FileShare.None))
            {
                using (var decryptedStream = File.Open(decryptedFileName, FileMode.Open, FileAccess.Read, FileShare.None))
                {
                    while ((originalStream.Read(buffer1, 0, buffer1.Length) > 0))
                    {
                        decryptedStream.Read(buffer2, 0, buffer2.Length);
                        Assert.IsTrue(buffer1.SequenceEqual(buffer2), "Files do not match.");
                    }
                }
            }
        }
Beispiel #12
0
        public void TestUnevenArraySize()
        {
            var hashset = new HashSet <string>();

            for (int i = 0; i < 10000; ++i)
            {
                hashset.Add(Convert.ToBase64String(SecureRandomizer.GetRandomBytes(1234)));
            }

            Assert.AreEqual(10000, hashset.Count, "Number of unique arrays");
        }
Beispiel #13
0
        public void TestTooLargeArrayStillWorks()
        {
            var hashset = new HashSet <string>();

            for (int i = 0; i < 20; ++i)
            {
                hashset.Add(Convert.ToBase64String(SecureRandomizer.GetRandomBytes(100000)));
            }

            Assert.AreEqual(20, hashset.Count, "Number of unique arrays");
        }
Beispiel #14
0
        /// <summary>
        /// Encrypts a message using 256-bit AES CBC encryption with HMACSHA256.
        /// </summary>
        /// <param name="input">The plaintext input.</param>
        /// <param name="cryptoKey">The 32-byte crypto key.</param>
        /// <param name="authKey">The 32-byte auth key.</param>
        /// <returns>The encrypted message. The first 16 bytes are the IV, followed by
        /// the ciphertext, then the last 32 bytes are the HMAC tag.</returns>
        public override EncryptionResults EncryptBytes(byte[] input, byte[] cryptoKey, byte[] authKey)
        {
            if (input == null)
            {
                return(new EncryptionResults(null));
            }
            ValidateKeys(cryptoKey, authKey);

            byte[] iv = SecureRandomizer.GetRandomBytes(IV_SIZE_BYTES);

            byte[] cipherText;
            using (var algo = new AesCryptoServiceProvider())
            {
                algo.Mode = CipherMode.CBC;
                using (var encryptor = algo.CreateEncryptor(cryptoKey, iv))
                {
                    using (var inputStream = new MemoryStream(input))
                    {
                        using (var memoryStream = new MemoryStream())
                        {
                            using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                            {
                                using (var binaryWriter = new BinaryWriter(cryptoStream))
                                {
                                    var buffer = new byte[Defaults.BUFFER_SIZE];
                                    int count;
                                    while ((count = inputStream.Read(buffer, 0, buffer.Length)) > 0)
                                    {
                                        binaryWriter.Write(buffer, 0, count);
                                    }
                                }
                            }
                            cipherText = memoryStream.ToArray();
                        }
                    }
                }
            }

            using (var hashAlgo = new HMACSHA256(authKey))
            {
                using (var memoryStream = new MemoryStream())
                {
                    using (var binaryWriter = new BinaryWriter(memoryStream))
                    {
                        binaryWriter.Write(iv);
                        binaryWriter.Write(cipherText);
                        binaryWriter.Flush();
                        var tag = hashAlgo.ComputeHash(memoryStream.ToArray());
                        binaryWriter.Write(tag);
                    }
                    return(new EncryptionResults(memoryStream.ToArray()));
                }
            }
        }
Beispiel #15
0
        public void TestAllArraysUnique()
        {
            var hashset = new HashSet <string>();
            var bytes   = new byte[32];

            for (int i = 0; i < 500000; ++i)
            {
                bytes = SecureRandomizer.GetRandomBytes(bytes.Length);
                hashset.Add(Convert.ToBase64String(bytes));
            }
            Assert.AreEqual(500000, hashset.Count, "Number of unique arrays");
        }
Beispiel #16
0
        public void TestSpeed()
        {
            var sw = new Stopwatch();

            sw.Start();
            var bytes = new byte[32];

            for (int i = 0; i < 100000; ++i)
            {
                bytes = SecureRandomizer.GetRandomBytes(bytes.Length);
            }

            Assert.IsTrue(sw.ElapsedMilliseconds < 2000, "Should have taken less than two seconds");
        }
Beispiel #17
0
        public void TestNotEmptyArray()
        {
            var bytes = new byte[32];

            for (int i = 0; i < 500000; ++i)
            {
                bytes = SecureRandomizer.GetRandomBytes(bytes.Length);
                bool anyNotZero = false;
                foreach (var b in bytes)
                {
                    anyNotZero |= (b != 0);
                }
                Assert.IsTrue(anyNotZero, "Array is full of zeros");
            }
        }
Beispiel #18
0
        public void TestUnicodeString(Symmetric_AES.KeySize keySize)
        {
            var    key   = Symmetric_AES.GenerateRandomKey(keySize);
            string input = Convert.ToBase64String(SecureRandomizer.GetRandomBytes(100)) + "\u01e2\u01f0\u020e\u0229";

            byte[] encrypted;
            string decrypted;

            using (var algorithm = new Symmetric_AES_CBC())
            {
                encrypted = algorithm.EncryptString(input, key);
            }
            using (var algorithm = new Symmetric_AES_CBC())
            {
                Assert.IsTrue(encrypted.Length > 100, "encrypted.Length");
                decrypted = algorithm.DecryptBytes(encrypted, key).AsString();
            }
            Assert.AreEqual(input, decrypted, string.Format("{0} | {1}", input, decrypted));
        }
Beispiel #19
0
        public void TestUnicodeString()
        {
            string passphrase = Guid.NewGuid().ToString("N");
            string input      = Convert.ToBase64String(SecureRandomizer.GetRandomBytes(100)) + "\u01e2\u01f0\u020e\u0229";

            byte[] encrypted;
            string decrypted;

            using (var algorithm = new Symmetric_AES_CBC_Passphrase())
            {
                encrypted = algorithm.EncryptString(input, passphrase);
            }
            using (var algorithm = new Symmetric_AES_CBC_Passphrase())
            {
                Assert.IsTrue(encrypted.Length > 100, "encrypted.Length");
                decrypted = algorithm.DecryptBytes(encrypted, passphrase).AsString();
            }
            Assert.AreEqual(input, decrypted, string.Format("{0} | {1}", input, decrypted));
        }
        public void TestUnicodeString()
        {
            byte[] cryptoKey, authKey;
            SymmetricAuthenticated_AES_HMACSHA256.GenerateKeys(out cryptoKey, out authKey);
            string input = Convert.ToBase64String(SecureRandomizer.GetRandomBytes(100)) + "\u01e2\u01f0\u020e\u0229";

            byte[] encrypted;
            string decrypted;

            using (var algorithm = new SymmetricAuthenticated_AES_HMACSHA256())
            {
                encrypted = algorithm.EncryptString(input, cryptoKey, authKey);
            }
            using (var algorithm = new SymmetricAuthenticated_AES_HMACSHA256())
            {
                Assert.IsTrue(encrypted.Length > 100, "encrypted.Length");
                decrypted = algorithm.DecryptBytes(encrypted, cryptoKey, authKey).AsString();
            }
            Assert.AreEqual(input, decrypted, string.Format("{0} | {1}", input, decrypted));
        }
        /// <summary>
        /// Encrypts a stream using a key derived from the passphrase.
        /// </summary>
        /// <param name="inputStream">The stream to encrypt.</param>
        /// <param name="outputStream">The encrypted stream.</param>
        /// <param name="passphrase">The passphrase from which the encryption key is derived.</param>
        public override void EncryptStream(Stream inputStream, Stream outputStream, string passphrase)
        {
            if (inputStream == null || outputStream == null)
            {
                throw new ArgumentNullException();
            }

            byte[] salt;
            byte[] key = PBKDF2.ComputeHash(passphrase, out salt, saltNumBytes: SALT_SIZE_BYTES, passwordNumBytes: KEY_SIZE_BYTES);

            byte[] iv       = null;
            int    ivLength = GetIVSizeBytes();

            if (ivLength != 0)
            {
                iv = SecureRandomizer.GetRandomBytes(ivLength);
                outputStream.Write(iv, 0, iv.Length);
            }

            outputStream.Write(salt, 0, salt.Length);

            using (var algo = new AesCryptoServiceProvider())
            {
                algo.Mode = GetCipherMode();
                using (var encryptor = algo.CreateEncryptor(key, iv))
                {
                    using (var cryptoStream = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write))
                    {
                        using (var binaryWriter = new BinaryWriter(cryptoStream))
                        {
                            var buffer = new byte[Defaults.BUFFER_SIZE];
                            int count;
                            while ((count = inputStream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                binaryWriter.Write(buffer, 0, count);
                            }
                        }
                    }
                }
            }
        }
Beispiel #22
0
        /// <summary>
        /// Encrypts a stream using a given key.
        /// </summary>
        /// <param name="inputStream">The stream to encrypt.</param>
        /// <param name="outputStream">The encrypted stream.</param>
        /// <param name="key">The key to use for encryption.</param>
        public override void EncryptStream(Stream inputStream, Stream outputStream, byte[] key)
        {
            ValidateKey(key);
            if (inputStream == null || outputStream == null)
            {
                throw new ArgumentNullException();
            }

            byte[] iv       = null;
            int    ivLength = GetIVSizeBytes();

            if (ivLength != 0)
            {
                iv = SecureRandomizer.GetRandomBytes(ivLength);
                outputStream.Write(iv, 0, iv.Length);
            }

            using (var algo = new AesCryptoServiceProvider())
            {
                algo.Mode = GetCipherMode();
                using (var encryptor = algo.CreateEncryptor(key, iv))
                {
                    using (var cryptoStream = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write))
                    {
                        using (var binaryWriter = new BinaryWriter(cryptoStream))
                        {
                            var buffer = new byte[Defaults.BUFFER_SIZE];
                            int count;
                            while ((count = inputStream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                binaryWriter.Write(buffer, 0, count);
                            }
                        }
                    }
                }
            }
        }
Beispiel #23
0
        public void TestThreadSafetyParallel()
        {
            var hashset = new HashSet <string>();

            Action <int> action = idx =>
            {
                for (int i = 0; i < 50000; ++i)
                {
                    byte[] bytes = SecureRandomizer.GetRandomBytes(32);
                    lock (hashset)
                    {
                        hashset.Add(Convert.ToBase64String(bytes));
                    }
                }
            };

            var parallelLoopResult = Parallel.For(0, 10, action);

            while (!parallelLoopResult.IsCompleted)
            {
            }

            Assert.AreEqual(500000, hashset.Count, "Number of unique arrays");
        }
Beispiel #24
0
 /// <summary>
 /// Generates a random key.
 /// </summary>
 /// <param name="keySize">The key size to use. Default is 32.</param>
 /// <returns>A random byte array which can be used as a key for AES encryption.</returns>
 public static byte[] GenerateRandomKey(KeySize keySize = KeySize.KeySize256Bit)
 {
     return(SecureRandomizer.GetRandomBytes((int)keySize));
 }
Beispiel #25
0
 /// <summary>
 /// Generates two random 32-byte arrays, for use with this class's encryption methods.
 /// </summary>
 /// <param name="cryptoKey">The 32-byte crypto key.</param>
 /// <param name="authKey">The 32-byte auth key.</param>
 public static void GenerateKeys(out byte[] cryptoKey, out byte[] authKey)
 {
     cryptoKey = SecureRandomizer.GetRandomBytes(KEY_SIZE_BYTES);
     authKey   = SecureRandomizer.GetRandomBytes(KEY_SIZE_BYTES);
 }
Beispiel #26
0
 public void SetUp()
 {
     _symmetric = new Symmetric_AES_CBC();
     _key       = SecureRandomizer.GetRandomBytes(32);
 }