From c31e74e75950572d7597612584d606d9962eba7c Mon Sep 17 00:00:00 2001 From: Simon Hughes Date: Wed, 11 Apr 2018 14:37:55 +0100 Subject: [PATCH] Updates to DiffieHellman --- DiffieHellman.cs | 34 +++++++------------ .../DiffieHellmanTests.cs | 31 ++++++++++++++--- Effortless.Net.Encryption.csproj | 1 + README.md | 9 +++++ 4 files changed, 50 insertions(+), 25 deletions(-) diff --git a/DiffieHellman.cs b/DiffieHellman.cs index 9fae118..6cd20a2 100644 --- a/DiffieHellman.cs +++ b/DiffieHellman.cs @@ -9,7 +9,6 @@ public sealed class DiffieHellman private readonly Aes _aes; private readonly ECDiffieHellmanCng _diffieHellman; public byte[] PublicKey { get; } - public byte[] IV => _aes.IV; public DiffieHellman() { @@ -25,37 +24,30 @@ public DiffieHellman() PublicKey = _diffieHellman.PublicKey.ToByteArray(); } - public byte[] Encrypt(byte[] publicKey, string secretMessage) + public byte[] Encrypt(DiffieHellman otherPerson, string secretMessage) { - byte[] encryptedMessage; - var key = CngKey.Import(publicKey, CngKeyBlobFormat.EccPublicBlob); - var derivedKey = _diffieHellman.DeriveKeyMaterial(key); // "Common secret" - - _aes.Key = derivedKey; + // Common secret created by Diffie Hellman + _aes.Key = _diffieHellman.DeriveKeyMaterial(CngKey.Import(otherPerson.PublicKey, CngKeyBlobFormat.EccPublicBlob)); using (var cipherText = new MemoryStream()) { using (var cs = new CryptoStream(cipherText, _aes.CreateEncryptor(), CryptoStreamMode.Write)) { - var ciphertextMessage = Encoding.UTF8.GetBytes(secretMessage); + var ciphertextMessage = Encoding.Unicode.GetBytes(secretMessage); cs.Write(ciphertextMessage, 0, ciphertextMessage.Length); cs.Close(); } - encryptedMessage = cipherText.ToArray(); + return cipherText.ToArray(); } - - return encryptedMessage; } - public string Decrypt(byte[] publicKey, byte[] encryptedMessage, byte[] iv) + public string Decrypt(DiffieHellman otherPerson, byte[] encryptedMessage) { - string decryptedMessage; - var key = CngKey.Import(publicKey, CngKeyBlobFormat.EccPublicBlob); - var derivedKey = _diffieHellman.DeriveKeyMaterial(key); - - _aes.Key = derivedKey; - _aes.IV = iv; + // Common secret created by Diffie Hellman + _aes.Key = _diffieHellman.DeriveKeyMaterial(CngKey.Import(otherPerson.PublicKey, CngKeyBlobFormat.EccPublicBlob)); + var backupIV = _aes.IV; + _aes.IV = otherPerson._aes.IV; using (var plainText = new MemoryStream()) { @@ -65,10 +57,10 @@ public string Decrypt(byte[] publicKey, byte[] encryptedMessage, byte[] iv) cs.Close(); } - decryptedMessage = Encoding.UTF8.GetString(plainText.ToArray()); - } + _aes.IV = backupIV; - return decryptedMessage; + return Encoding.Unicode.GetString(plainText.ToArray()); + } } } } \ No newline at end of file diff --git a/Effortless.Net.Encryption.Tests.Unit/Effortless.Net.Encryption.Tests.Unit/DiffieHellmanTests.cs b/Effortless.Net.Encryption.Tests.Unit/Effortless.Net.Encryption.Tests.Unit/DiffieHellmanTests.cs index ae93ff8..30c2e6c 100644 --- a/Effortless.Net.Encryption.Tests.Unit/Effortless.Net.Encryption.Tests.Unit/DiffieHellmanTests.cs +++ b/Effortless.Net.Encryption.Tests.Unit/Effortless.Net.Encryption.Tests.Unit/DiffieHellmanTests.cs @@ -8,18 +8,41 @@ public class DiffieHellmanTests [Test] public void Encrypt_Decrypt() { - var text = "Hello World!"; + const string text = "Hello World!"; - var bob = new DiffieHellman(); var alice = new DiffieHellman(); + var bob = new DiffieHellman(); // Bob uses Alice's public key to encrypt his message. - var secretMessage = bob.Encrypt(alice.PublicKey, text); + var secretMessage = bob.Encrypt(alice, text); // Alice uses Bob's public key and IV to decrypt the secret message. - var decryptedMessage = alice.Decrypt(bob.PublicKey, secretMessage, bob.IV); + var decryptedMessage = alice.Decrypt(bob, secretMessage); + Assert.AreEqual(text, decryptedMessage); + } + + [Test] + public void MultipleTests() + { + const string text = "Hello World!"; + var alice = new DiffieHellman(); + var bob = new DiffieHellman(); + + var secretMessageA = alice.Encrypt(bob, text); + var secretMessage1 = bob.Encrypt(alice, text); + var decryptedMessage = alice.Decrypt(bob, secretMessage1); + var secretMessageB = alice.Encrypt(bob, text); Assert.AreEqual(text, decryptedMessage); + Assert.AreEqual(secretMessageA, secretMessageB); + + // See if its repeatable due to IV being replaced by previous decryption + var secretMessage2 = bob.Encrypt(alice, text); + decryptedMessage = alice.Decrypt(bob, secretMessage2); + Assert.AreEqual(text, decryptedMessage); + + // Should be the same if nothing has changed + Assert.AreEqual(secretMessage1, secretMessage2); } } } \ No newline at end of file diff --git a/Effortless.Net.Encryption.csproj b/Effortless.Net.Encryption.csproj index 2aa0e21..de0814e 100644 --- a/Effortless.Net.Encryption.csproj +++ b/Effortless.Net.Encryption.csproj @@ -56,6 +56,7 @@ + \ No newline at end of file diff --git a/README.md b/README.md index a79729f..c9b6d00 100644 --- a/README.md +++ b/README.md @@ -65,4 +65,13 @@ ds.AssignNewKey(); var signature = ds.SignData(hash); var result = ds.VerifySignature(hash, signature); Assert.IsTrue(result); + +// Diffie Hellman +var alice = new DiffieHellman(); +var bob = new DiffieHellman(); +// Bob uses Alice's public key to encrypt his message. +var secretMessage = bob.Encrypt(alice, "Hello"); +// Alice uses Bob's public key and IV to decrypt the secret message. +var decryptedMessage = alice.Decrypt(bob, secretMessage); +Assert.AreEqual("Hello", decryptedMessage); ```