public void Encrypt_Should_Throw_Crypto_Exception_If_RSA_Public_Key_Is_Invalid()
        {
            byte[] fileBytes = Random.GetNumbers(2048);

            asymmetricPublicKey.Modulus = new byte[1];

            Assert.That(() => { HybridEncryption.Encrypt(DataType.File, fileBytes, asymmetricPublicKey); }, Throws.InstanceOf(typeof(CryptoException)));
        }
Пример #2
0
        public void Hashing_Can_Generate_Same_Hash_For_Same_Data()
        {
            byte[] data  = Random.GetNumbers(256);
            byte[] hash1 = Hashing.HmacSha(data, key);
            byte[] hash2 = Hashing.HmacSha(data, key);

            CollectionAssert.AreEqual(hash1, hash2);
        }
Пример #3
0
        public void Hashing_Can_Generate_Hash_Of_Data()
        {
            byte[] data = Random.GetNumbers(256);
            byte[] hash = Hashing.HmacSha(data, key);

            Assert.NotNull(hash);
            CollectionAssert.IsNotEmpty(hash);
        }
        public void Can_Recover_Encrypted_File()
        {
            byte[]          fileBytes       = Random.GetNumbers(2048);
            EncryptedPacket encryptedPacket = HybridEncryption.Encrypt(DataType.File, fileBytes, asymmetricPublicKey);

            byte[] decryptedBytes = HybridEncryption.Decrypt(encryptedPacket, asymmetricPublicKey);

            CollectionAssert.AreEqual(fileBytes, decryptedBytes);
        }
        public void Encryption_Generates_Different_Hmac_Each_Time()
        {
            byte[] fileBytes = Random.GetNumbers(2048);

            EncryptedPacket encryptedPacket1 = HybridEncryption.Encrypt(DataType.File, fileBytes, asymmetricPublicKey);
            EncryptedPacket encryptedPacket2 = HybridEncryption.Encrypt(DataType.File, fileBytes, asymmetricPublicKey);

            CollectionAssert.AreNotEqual(encryptedPacket1.Hmac, encryptedPacket2.Hmac);
        }
        public void Encryption_Generates_New_Aes_Key_Each_Time()
        {
            byte[] fileBytes = Random.GetNumbers(2048);

            EncryptedPacket encryptedPacket1 = HybridEncryption.Encrypt(DataType.File, fileBytes, asymmetricPublicKey);
            EncryptedPacket encryptedPacket2 = HybridEncryption.Encrypt(DataType.File, fileBytes, asymmetricPublicKey);

            CollectionAssert.AreNotEqual(encryptedPacket1.EncryptedSessionKey, encryptedPacket2.EncryptedSessionKey);
        }
Пример #7
0
        public void Hashing_Generates_Different_Hash_For_Different_Data()
        {
            byte[] data1 = Random.GetNumbers(256);
            byte[] data2 = Random.GetNumbers(256);

            byte[] hash1 = Hashing.HmacSha(data1, key);
            byte[] hash2 = Hashing.HmacSha(data2, key);

            CollectionAssert.AreNotEqual(hash1, hash2);
        }
Пример #8
0
        public void Hash_Compare_Can_Compare_Hashes_Of_Equal_Length_Correctly()
        {
            int hashLength = 128;

            byte[] hash1 = Random.GetNumbers(hashLength);

            byte[] hash2 = new byte[hashLength];
            Buffer.BlockCopy(hash1, 0, hash2, 0, hash1.Length);

            Assert.True(Hashing.CompareHashes(hash1, hash2));
        }
        public void Can_Encrypt_Stream_Of_Data()
        {
            byte[] fileBytes = Random.GetNumbers(2048);

            MemoryStream inputStream = new MemoryStream(fileBytes);

            EncryptedPacket encryptedPacket = HybridEncryption.EncryptFile(inputStream, asymmetricPublicKey);

            Assert.NotNull(encryptedPacket);
            CollectionAssert.AreNotEqual(fileBytes, encryptedPacket.EncryptedData);
        }
Пример #10
0
        public void Hash_Compare_Can_Compare_Hashes_Of_Unequal_Length_Correctly()
        {
            int hashLength = 256;

            byte[] hash1 = Random.GetNumbers(hashLength);

            byte[] hash2 = new byte[hashLength - 1];
            Buffer.BlockCopy(hash1, 0, hash2, 0, hashLength - 1);

            Assert.False(Hashing.CompareHashes(hash1, hash2));
        }
        public void Decryption_Throws_CryptoException_When_Hmac_Differs()
        {
            byte[] fileBytes = Random.GetNumbers(2048);

            EncryptedPacket encryptedPacket = HybridEncryption.Encrypt(DataType.File, fileBytes, asymmetricPublicKey);

            encryptedPacket.Hmac[25] = (byte)((encryptedPacket.Hmac[25] + 1) % 255);

            Assert.Throws(typeof(CryptoException), () =>
            {
                HybridEncryption.Decrypt(encryptedPacket, asymmetricPublicKey);
            });
        }
        public void Can_Encrypt_Small_File()
        {
            byte[] fileBytes = Random.GetNumbers(256);

            EncryptedPacket encryptedPacket = null;

            Assert.DoesNotThrow(() =>
            {
                encryptedPacket = HybridEncryption.Encrypt(DataType.File, fileBytes, asymmetricPublicKey);
            });

            Assert.NotNull(encryptedPacket);
            Assert.That(encryptedPacket.DataType, Is.EqualTo(DataType.File), "EncryptedPacket DataType property not set correctly");
        }
        /// <summary>
        /// Encrypt a file
        /// </summary>
        /// <param name="inputStream">File to read data from</param>
        /// <param name="publicKey"></param>
        /// <returns>EncryptedPacket with all info for receiver to decrypt</returns>
        public static EncryptedPacket EncryptFile(Stream inputStream, RSAParameters publicKey)
        {
            MemoryStream outputStream = new MemoryStream();

            byte[] aesKey = Random.GetNumbers(32);
            byte[] iv     = Random.GetNumbers(16);

            EncryptedPacket encryptedPacket = new EncryptedPacket
            {
                DataType            = DataType.File,
                EncryptedSessionKey = AsymmetricEncryption.Encrypt(aesKey, publicKey),
                Iv = iv
            };

            try
            {
                // create streamers
                using (HashStreamer hashStreamer = new HashStreamer(aesKey))
                    using (SymmetricStreamer symmetricStreamer = new SymmetricStreamer(aesKey, iv))
                    {
                        // create streams
                        var hmacStream      = hashStreamer.HmacShaStream(outputStream, aesKey, CryptoStreamMode.Write);
                        var encryptedStream = symmetricStreamer.EncryptStream(hmacStream, CryptoStreamMode.Write);

                        // read all data
                        inputStream.CopyTo(encryptedStream);

                        // get hash
                        encryptedPacket.Hmac = hashStreamer.Hash;

                        // create signature
                        encryptedPacket.Signature = AsymmetricEncryption.Sign(encryptedPacket.Hmac);

                        // close file streams
                        inputStream.Close();
                    }
            }
            catch (CryptographicException e)
            {
                throw new CryptoException("Error while encrypting stream", e);
            }

            // read encrypted data from memory stream
            encryptedPacket.EncryptedData = outputStream.ToArray();

            return(encryptedPacket);
        }
        public void Encryption_Populates_All_Packet_Fields()
        {
            byte[]          fileBytes       = Random.GetNumbers(2048);
            EncryptedPacket encryptedPacket = HybridEncryption.Encrypt(DataType.File, fileBytes, asymmetricPublicKey);

            Assert.NotNull(encryptedPacket.EncryptedSessionKey, "AES key not set");
            CollectionAssert.IsNotEmpty(encryptedPacket.EncryptedSessionKey, "AES key not set");

            Assert.NotNull(encryptedPacket.Iv, "AES IV not set");
            CollectionAssert.IsNotEmpty(encryptedPacket.Iv, "AES IV not set");

            Assert.NotNull(encryptedPacket.Hmac, "HMAC not set");
            CollectionAssert.IsNotEmpty(encryptedPacket.Hmac, "HMAC not set");

            Assert.NotNull(encryptedPacket.EncryptedData, "Encrypted data not set");
            CollectionAssert.IsNotEmpty(encryptedPacket.EncryptedData, "Encrypted data not set");
        }
        public void Can_Decrypt_Stream()
        {
            // raw data
            byte[] rawData = Random.GetNumbers(4096);

            // encrypt with known good encryptor
            byte[]       encryptedBytes        = SymmetricEncryption.Encrypt(rawData, key, iv);
            MemoryStream encryptedMemoryStream = new MemoryStream(encryptedBytes);

            // attempt to decrypt, then put decrypted stream into a memory stream and put that stream into an array
            CryptoStream decryptedStream       = streamer.DecryptStream(encryptedMemoryStream, CryptoStreamMode.Read);
            MemoryStream decryptedMemoryStream = new MemoryStream();

            decryptedStream.CopyTo(decryptedMemoryStream);
            byte[] decryptedBytes = decryptedMemoryStream.ToArray();

            CollectionAssert.AreEqual(rawData, decryptedBytes);
        }
        public async Task Can_Decrypt_Stream_Of_Data()
        {
            byte[] fileBytes = Random.GetNumbers(2048);

            MemoryStream rawStream = new MemoryStream(fileBytes);

            MemoryStream encryptedBytes = new MemoryStream();
            await HybridEncryption.EncryptFile(rawStream, encryptedBytes, asymmetricPublicKey);

            encryptedBytes.Position = 0;

            MemoryStream decryptedStream = new MemoryStream();
            bool         hashOk          = await HybridEncryption.DecryptFile(encryptedBytes, decryptedStream, asymmetricPublicKey);

            decryptedStream.Position = 0;
            byte[] decryptedBytes = decryptedStream.ToArray();

            Assert.True(hashOk);
            CollectionAssert.IsNotEmpty(decryptedBytes);
            CollectionAssert.AreEqual(fileBytes, decryptedBytes);
        }
        /// <summary>
        /// Encrypt data
        /// </summary>
        /// <param name="type">Type of data</param>
        /// <param name="data">Data to be encrypted</param>
        /// <param name="publicKey">Public key of receiver</param>
        /// <exception cref="CryptoException"></exception>
        /// <returns>EncryptedPacket with all info for receiver to decrypt</returns>
        public static EncryptedPacket Encrypt(DataType type, byte[] data, RSAParameters publicKey)
        {
            // create AES session key
            byte[] sessionKey = Random.GetNumbers(32);

            // create AES IV
            byte[] iv = Random.GetNumbers(16);

            // encrypt AES session key with RSA
            byte[] encryptedSessionKey;
            try
            {
                encryptedSessionKey = AsymmetricEncryption.Encrypt(sessionKey, publicKey);
            }
            catch (CryptographicException e)
            {
                throw new CryptoException("Error while encrypting AES session key", e);
            }

            // encrypt data with AES
            byte[] encryptedData;
            try
            {
                encryptedData = SymmetricEncryption.Encrypt(data, sessionKey, iv);
            }
            catch (NullReferenceException)
            {
                throw new CryptoException("Data was null");
            }
            catch (CryptographicException e)
            {
                throw new CryptoException("Error while encrypting data", e);
            }


            // generate hash of encrypted data with session key
            byte[] hash;
            try
            {
                hash = Hashing.HmacSha(encryptedData, sessionKey);
            }
            catch (CryptographicException e)
            {
                throw new CryptoException("Error while hashing data", e);
            }


            // generate signature using hash
            byte[] signature;
            try
            {
                signature = AsymmetricEncryption.Sign(hash);
            }
            catch (CryptographicException e)
            {
                throw new CryptoException("Error while creating signature", e);
            }

            // put all info into new EncryptedPacket
            var encryptedPacket = new EncryptedPacket
            {
                DataType            = type,
                EncryptedSessionKey = encryptedSessionKey,
                Iv            = iv,
                Hmac          = hash,
                Signature     = signature,
                EncryptedData = encryptedData
            };

            return(encryptedPacket);
        }
        /// <summary>
        /// Encrypt a file and store all data in another file
        /// </summary>
        /// <param name="inputStream">Stream to read data from</param>
        /// <param name="outputStream">Stream to write encrypted packet to</param>
        /// <param name="publicKey"></param>
        /// <returns>Length of output stream</returns>
        public static async Task <long> EncryptFile(Stream inputStream, Stream outputStream, RSAParameters publicKey)
        {
            byte[] aesKey = Random.GetNumbers(32);
            byte[] iv     = Random.GetNumbers(16);

            // write header
            byte[] encryptedSessionKey = AsymmetricEncryption.Encrypt(aesKey, publicKey);

            List <byte> firstData = new List <byte>();

            firstData.Add((byte)DataType.File);
            firstData.AddRange(BitConverter.GetBytes((ushort)encryptedSessionKey.Length));
            firstData.AddRange(encryptedSessionKey);
            firstData.AddRange(iv);

            await outputStream.WriteAsync(firstData.ToArray(), 0, firstData.Count); // write datatype, encrypted aes key and aes iv

            await outputStream.FlushAsync();

            await outputStream.WriteAsync(new byte[64], 0, 64); // reserve space for hmac

            await outputStream.FlushAsync();

            int signatureLength = publicKey.Modulus.Length;
            await outputStream.WriteAsync(new byte[signatureLength], 0, signatureLength); // reserve space for signature

            await outputStream.FlushAsync();

            try
            {
                using (HashStreamer hashStreamer = new HashStreamer(aesKey))
                    using (SymmetricStreamer symmetricStreamer = new SymmetricStreamer(aesKey, iv))
                    {
                        var hmacStream      = hashStreamer.HmacShaStream(outputStream, aesKey, CryptoStreamMode.Write);
                        var encryptedStream = symmetricStreamer.EncryptStream(hmacStream, CryptoStreamMode.Write);
                        outputStream.SetLength(firstData.Count + 64 + signatureLength);
                        outputStream.Position = firstData.Count + 64 + signatureLength;

                        await inputStream.CopyToAsync(encryptedStream);

                        // write hash in front of file
                        outputStream.Position = 0;
                        await outputStream.WriteAsync(firstData.ToArray(), 0, firstData.Count);

                        byte[] hash = hashStreamer.Hash;
                        await outputStream.WriteAsync(hash, 0, 64);

                        // write signature in front of file
                        await outputStream.WriteAsync(AsymmetricEncryption.Sign(hash), 0, signatureLength);

                        // flush it all the way
                        await outputStream.FlushAsync();

                        return(outputStream.Length);
                    }
            }
            catch (CryptographicException e)
            {
                throw new CryptoException("Error while encrypting file", e);
            }
        }
 public void SetUp()
 {
     key      = Random.GetNumbers(32);
     iv       = Random.GetNumbers(16);
     streamer = new SymmetricStreamer(key, iv);
 }
Пример #20
0
 public void Setup()
 {
     key = Random.GetNumbers(32);
 }