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))); }
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); }
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); }
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); }
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); }
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); }
public void Setup() { key = Random.GetNumbers(32); }