Example #1
0
 /// <summary>
 /// Decrypts the string.
 /// </summary>
 /// <param name="data">The data.</param>
 /// <param name="encoding">The encoding.</param>
 /// <returns></returns>
 public string DecryptString(string data, Encoding encoding)
 {
     using (var asym = Asymmetric.GetInstanceFromCertStore(_storeNameParam, _storeLocationParam, _thumbprintParam))
     {
         return(asym.DecryptString(data, encoding));
     }
 }
Example #2
0
 /// <summary>
 /// Decrypts the specified data.
 /// </summary>
 /// <param name="data">The data.</param>
 /// <returns></returns>
 public byte[] Decrypt(byte[] data)
 {
     using (var asym = Asymmetric.GetInstanceFromCertStore(_storeNameParam, _storeLocationParam, _thumbprintParam))
     {
         return(asym.DecryptBytes(data));
     }
 }
Example #3
0
        public void TestNoiseXx()
        {
            var rootKey  = PublicKeyAuth.GenerateKeyPair();
            var Verifier = DiscoHelper.CreatePublicKeyVerifier(rootKey.PublicKey);

            var clienPair  = Asymmetric.GenerateKeyPair();
            var serverPair = Asymmetric.GenerateKeyPair();

            // init
            var clientConfig = new Config
            {
                KeyPair              = clienPair,
                HandshakePattern     = NoiseHandshakeType.NoiseXX,
                PublicKeyVerifier    = Verifier,
                StaticPublicKeyProof = DiscoHelper.CreateStaticPublicKeyProof(rootKey.PrivateKey, clienPair.PublicKey)
            };

            var serverConfig = new Config
            {
                KeyPair              = serverPair,
                HandshakePattern     = NoiseHandshakeType.NoiseXX,
                PublicKeyVerifier    = Verifier,
                StaticPublicKeyProof = DiscoHelper.CreateStaticPublicKeyProof(rootKey.PrivateKey, serverPair.PublicKey)
            };

            this.RunTwoWayTest(clientConfig, serverConfig, 1802);
        }
Example #4
0
        public void Init()
        {
            var sut = new Asymmetric();

            PublicKey  = sut.PublicKey;
            PrivateKey = sut.PrivateKey;
        }
Example #5
0
        /// <summary>
        /// Generate a disco key pair (X25519 key pair)
        /// and save it to a file in hexadecimal form.
        /// </summary>
        /// <param name="fileName">Filepath to save key</param>
        /// <returns>Disco key pair</returns>
        public static KeyPair GenerateAndSaveDiscoKeyPair(string fileName)
        {
            var keyPair = Asymmetric.GenerateKeyPair();

            File.WriteAllText(fileName, keyPair.ExportPublicKey() + keyPair.ExportPrivateKey());

            return(keyPair);
        }
Example #6
0
        public void Encrypt_Decrypt_Equal()
        {
            var sut            = new Asymmetric();
            var encryptedBytes = sut.Encrypt(PlainText);
            var decryptedText  = sut.Decrypt(encryptedBytes);

            Assert.AreEqual(PlainText, decryptedText);
        }
Example #7
0
        public void EncryptWithPrivatePemTest()
        {
            var pem = File.ReadAllText(Path.Join(path, @"Data\certificate.pem")) + File.ReadAllText(Path.Join(path, @"Data\private.pem"));
            var rsa = Asymmetric.FromPem(pem);

            var cipher = rsa.Encrypt("Attack at dawn!");

            Assert.AreEqual("Attack at dawn!", rsa.Decrypt(cipher));
        }
Example #8
0
        public void AsymmetricEncryptDataTest()
        {
            Asymmetric asymmetric = new Asymmetric();

            // Short data test
            byte[] data = new byte[] { 7, 12, 69, 47, 249 };

            byte[] encrypted = asymmetric.EncryptData(data, mainPublicKey);
            byte[] actual = asymmetric.DecryptData(encrypted, mainPrivateKey);
            AssertBytesAreEqual(data, actual);

            // Longer data test
            string msg =
                "Implementing the IDisposable interface can be the source of great " +
                "confusion amongst many programmers. Whenever possible, I use the following " +
                "pattern when implementing it. So far it covers most of the cases I have needed " +
                "but for a more extensive discussion see this excellent article by Scott Dorman: " +
                "www.codeproject.com/KB/cs/idisposable.aspx";
            data = Encoding.Unicode.GetBytes(msg);
            encrypted = asymmetric.EncryptData(data, mainPublicKey);
            actual = asymmetric.DecryptData(encrypted, mainPrivateKey);
            AssertBytesAreEqual(data, actual);

            // Null argument
            data = null;
            try
            {
                encrypted = asymmetric.EncryptData(data, mainPublicKey);
                Assert.Fail("Expected exception");
            }
            catch (ArgumentNullException)
            {
            }

            // Zero data length
            data = new byte[0];
            encrypted = asymmetric.EncryptData(data, mainPublicKey);
            actual = asymmetric.DecryptData(encrypted, mainPrivateKey);
            AssertBytesAreEqual(data, actual);

            // Single byte
            data = new byte[] { 7 };
            encrypted = asymmetric.EncryptData(data, mainPublicKey);
            actual = asymmetric.DecryptData(encrypted, mainPrivateKey);
            AssertBytesAreEqual(data, actual);

            // Long data test
            data = new byte[2 * 1024 * 1024];
            Random random = new Random(71269);
            random.NextBytes(data);
            encrypted = asymmetric.EncryptData(data, mainPublicKey);
            actual = asymmetric.DecryptData(encrypted, mainPrivateKey);
            AssertBytesAreEqual(data, actual);
        }
        public void HashStringHashesStringWhereEntropyIsNull()
        {
            var asymmetric = new Asymmetric();

            string entropy = null;

            var salt = Utility.GenerateSalt();

            var hash = asymmetric.HashString(password, salt, entropy);

            Assert.Fail();
        }
        public void HashStringHashesStringWhereSaltIsEmptyString()
        {
            var asymmetric = new Asymmetric();

            var entropy = string.Empty;

            var salt = "";

            var hash = asymmetric.HashString(password, salt, entropy);

            Assert.Fail();
        }
Example #11
0
        public void BasicCanDecryptTest()
        {
            const string PLAINTEXT  = "This is a test of the SmartEncryption system...";
            var          senderKeys = Asymmetric.GenerateKeyPair();
            var          recipKeys  = Asymmetric.GenerateKeyPair();

            var cipher = Asymmetric.Encrypt(Encoding.UTF8.GetBytes(PLAINTEXT), senderKeys.PrivateKey,
                                            recipKeys.PublicKey);
            var plain = Asymmetric.Decrypt(cipher, recipKeys.PrivateKey, senderKeys.PublicKey);

            Assert.AreEqual(PLAINTEXT, Encoding.UTF8.GetString(plain));
        }
Example #12
0
        static void ComparisonTest()
        {
            var filePath = Directory.GetCurrentDirectory() + "/test.csv";
            var lines    = new List <string>();
            var message  = "AAAAAAAA";

            var timer = new Stopwatch();

            lines.Add("Characters,DES3,RSA");

            for (var j = 0; j < 100; j++)
            {
                timer.Start();
                for (var i = 0; i < 100; i++)
                {
                    var symmetricKey = Symmetric.Generate3DESKey();
                    var encrypted    = Symmetric.Encrypt3DES(symmetricKey, message.GetBytes());
                    var decrypted    = Symmetric.Decrypt3DES(symmetricKey, encrypted);
                    if (decrypted.GetString() != message)
                    {
                        Console.WriteLine("ERROR: Encryption Failed");
                        return;
                    }
                }
                timer.Stop();

                var symmetricTime = timer.ElapsedMilliseconds;

                timer.Reset();

                timer.Start();
                for (var i = 0; i < 100; i++)
                {
                    var asymetricKey = Asymmetric.GenerateRSAKeys();
                    var encrypted    = Asymmetric.EncryptRSA(asymetricKey.Public, message.GetBytes());
                    var decrypted    = Asymmetric.DecryptRSA(asymetricKey.Private, encrypted);
                    if (decrypted.GetString() != message)
                    {
                        Console.WriteLine("ERROR: Encryption Failed");
                        return;
                    }
                }
                timer.Stop();

                var asymetricTime = timer.ElapsedMilliseconds;

                lines.Add(string.Format("{0},{1},{2}", message.Length, symmetricTime, asymetricTime));
                message += "AAAAAAAA";
            }

            File.WriteAllLines(filePath, lines);
        }
        public void HashStringHashesStringWherePasswordEmptyString()
        {
            var asymmetric = new Asymmetric();

            var entropy = string.Empty;

            var salt     = Utility.GenerateSalt();
            var password = "";

            var hash = asymmetric.HashString(password, salt, entropy);

            Assert.Fail();
        }
Example #14
0
 public void Decrypt_Cipher_Size_Exception()
 {
     try
     {
         var sut = new Asymmetric(privateKey: PrivateKey);
         sut.Decrypt(new byte[100]);
     }
     catch (Exception ex)
     {
         Assert.AreEqual("Parameter encryptedBytes must be divisible by 256.", ex.Message);
         throw;
     }
 }
Example #15
0
 public void Decrypt_No_Private_Key_Exception()
 {
     try
     {
         var sut = new Asymmetric(PublicKey);
         sut.Decrypt(new byte[100]);
     }
     catch (Exception ex)
     {
         Assert.AreEqual("PrivateKey missing.", ex.Message);
         throw;
     }
 }
Example #16
0
 public void Encrypt_No_Public_Key_Exception()
 {
     try
     {
         var sut = new Asymmetric(privateKey: PrivateKey);
         sut.Encrypt(PlainText);
     }
     catch (Exception ex)
     {
         Assert.AreEqual("PublicKey missing.", ex.Message);
         throw;
     }
 }
Example #17
0
        public void Encrypt_Decrypt_Existing_Key_Pair_Equal()
        {
            var encryptor = new Asymmetric(PublicKey);
            var decryptor = new Asymmetric(privateKey: PrivateKey);

            Assert.IsNull(encryptor.PrivateKey);
            Assert.IsNull(decryptor.PublicKey);

            var encryptedBytes = encryptor.Encrypt(PlainText);
            var decryptedText  = decryptor.Decrypt(encryptedBytes);

            Assert.AreEqual(PlainText, decryptedText);
        }
Example #18
0
        /// <summary>
        /// Performs the actual job of disposing the object.
        /// </summary>
        /// <param name="disposing">
        /// Passes the information whether this method is called by <see cref="Dispose()"/> (explicitly or
        /// implicitly at the end of a <c>using</c> statement), or by the <see cref="M:~RsaXmlSigner"/>.
        /// </param>
        /// <remarks>
        /// If the method is called with <paramref name="disposing"/><c>==true</c>, i.e. from <see cref="Dispose()"/>,
        /// it will try to release all managed resources (usually aggregated objects which implement <see cref="IDisposable"/> as well)
        /// and then it will release all unmanaged resources if any. If the parameter is <c>false</c> then
        /// the method will only try to release the unmanaged resources.
        /// </remarks>
        protected virtual void Dispose(bool disposing)
        {
            // if it is disposed or in a process of disposing - return.
            if (Interlocked.Exchange(ref _disposed, 1) != 0)
            {
                return;
            }

            if (disposing)
            {
                Asymmetric.Dispose();
            }
        }
Example #19
0
        public static bool DecryptBlackBoxFile(string decryptedFileName, string readFileName)
        {
            byte[] encryptedBytes = File.ReadAllBytes(readFileName);
            byte[] decryptedBytes = Asymmetric.Decrypt(encryptedBytes);

            if (decryptedBytes != null)
            {
                File.WriteAllBytes(decryptedFileName, decryptedBytes);
                return(true);
            }

            return(false);
        }
Example #20
0
        public IActionResult Decrypt(string ciphertext)
        {
            string privateKey = _configuration["Asymmetric:PrivateKey"];

            Asymmetric a = new Asymmetric();

            byte[] decryptedBytes = a.Decrypt(ciphertext, privateKey);

            ViewBag.Ciphertext = ciphertext;
            ViewBag.Plaintext  = Encoding.UTF8.GetString(decryptedBytes);

            return(View());
        }
Example #21
0
        static void RunBasicScenarioDebug(string message)
        {
            var messageBytes = message.GetBytes();

            var hash = message.GetHash(HashTypes.SHALE);

            var aliceKeys = Asymmetric.GenerateRSAKeys();
            var bobKeys   = Asymmetric.GenerateRSAKeys();

            var encryptedHash = Asymmetric.EncryptRSA(aliceKeys.Private, hash);

            var augmentedMessage = Helper.CombineByteArrays(messageBytes, encryptedHash);

            var DES3Key = Symmetric.Generate3DESKey();

            var encryptedMessage = Symmetric.Encrypt3DES(DES3Key, augmentedMessage);

            var encryptedKey = Asymmetric.EncryptRSA(bobKeys.Public, DES3Key);

            var transmissionMessage = Helper.CombineByteArrays(encryptedMessage, encryptedKey);

            var recoveredEncryptedKey = new byte[30];
            var recoveredCipherText   = new byte[transmissionMessage.Length - recoveredEncryptedKey.Length];

            SplitMessage(ref recoveredEncryptedKey, ref recoveredCipherText, transmissionMessage);

            var decrypedDES3Key = Asymmetric.DecryptRSA(bobKeys.Private, recoveredEncryptedKey);

            var decryptedMessage = Symmetric.Decrypt3DES(decrypedDES3Key, recoveredCipherText);

            var recoveredSignature = new byte[5];
            var recoveredMessage   = new byte[decryptedMessage.Length - recoveredSignature.Length];

            SplitMessage(ref recoveredSignature, ref recoveredMessage, decryptedMessage);

            var decryptedHash = Asymmetric.DecryptRSA(aliceKeys.Public, recoveredSignature);

            var recoveredMessageHash = recoveredMessage.GetString().GetHash(HashTypes.SHALE);

            if (decryptedHash.SequenceEqual(recoveredMessageHash))
            {
                Console.WriteLine("Hashes are identical");
                Console.WriteLine("This means we can be sure the message is from Alice and was unaltered");
            }
            else
            {
                Console.WriteLine("Hashes are different");
                Console.WriteLine("This means either the message was not from Alice, or it was altered during transmission");
            }
        }
Example #22
0
        public IActionResult Encrypt(string plaintext)
        {
            string publicKey = _configuration["Asymmetric:PublicKey"];

            Asymmetric a = new Asymmetric();

            byte[] encryptedBytes = a.Encrypt(plaintext, publicKey);

            ViewBag.Plaintext      = plaintext;
            ViewBag.EncryptedBytes = Encoding.UTF8.GetString(encryptedBytes);
            ViewBag.Ciphertext     = Convert.ToBase64String(encryptedBytes);

            return(View());
        }
Example #23
0
        public void VerifyUsingPublicPemTest()
        {
            // Create a signature with the PFX file.
            var signature = new Asymmetric(Path.Join(path, @"Data\certificate.pfx"), password).Sign(message.ToBytes());

            // Use the PEM certificate to verify the signature.
            var pem = File.ReadAllText(Path.Join(path, @"Data\certificate.pem"));
            var rsa = Asymmetric.FromPem(pem);

            Assert.IsTrue(rsa.Verify(message.ToBytes(), signature));
            Assert.IsTrue(rsa.Verify(message.ToBytes(), signatureBase64.FromBase64()));

            // We should not be allowed to sign with just a public key.
            Assert.ThrowsException <Exception>(() => { rsa.Sign(message.ToBytes()); });
        }
Example #24
0
        public void EncryptAndSignUsingPfxTest()
        {
            var rsa = new Asymmetric(Path.Join(path, @"Data\certificate.pfx"), password);

            // EXAMPLE WITH STRING
            var signature = rsa.Sign(message);

            Assert.IsTrue(rsa.Verify(message, signature));
            var cipher = rsa.Encrypt(message);

            Assert.AreEqual(message, rsa.Decrypt(cipher));

            // CONDENSED EXAMPLE WITH BYTES
            Assert.IsTrue(rsa.Verify(message, rsa.Sign(message)));
            Assert.AreEqual(message, rsa.Decrypt(rsa.Encrypt(message)));
        }
        public void HashStringHashesStringWhereEntrpoyEmptyString()
        {
            var asymmetric = new Asymmetric();

            var entropy = string.Empty;

            var salt = Utility.GenerateSalt();

            var hash = asymmetric.HashString(password, salt, entropy);

            Trace.WriteLine(salt);
            Trace.WriteLine(entropy);
            Trace.WriteLine(hash);

            Assert.IsTrue(hash.Equals(asymmetric.HashString(password, salt, entropy), StringComparison.Ordinal));
        }
Example #26
0
        public void TestNoiseN()
        {
            // init
            var clientConfig = new Config
            {
                KeyPair          = Asymmetric.GenerateKeyPair(),
                HandshakePattern = NoiseHandshakeType.NoiseN
            };

            var serverConfig = new Config
            {
                KeyPair          = Asymmetric.GenerateKeyPair(),
                HandshakePattern = NoiseHandshakeType.NoiseN
            };

            this.RunOneWayTest(clientConfig, serverConfig, 1803);
        }
Example #27
0
        static void CompareSpeeds(string message)
        {
            var timer = new Stopwatch();

            var messageBytes = message.GetBytes();
            var symmetricKey = Symmetric.Generate3DESKey();
            var asymetricKey = Asymmetric.GenerateRSAKeys();

            timer.Start();
            for (var i = 0; i < 100; i++)
            {
                var encrypted = Symmetric.Encrypt3DES(symmetricKey, messageBytes);
                var decrypted = Symmetric.Decrypt3DES(symmetricKey, encrypted);
                if (decrypted.GetString() != message)
                {
                    Console.WriteLine("ERROR: Encryption Failed");
                    return;
                }
            }
            timer.Stop();

            var symmetricTime = timer.ElapsedMilliseconds;

            timer.Reset();

            timer.Start();
            for (var i = 0; i < 100; i++)
            {
                var encrypted = Asymmetric.EncryptRSA(asymetricKey.Public, messageBytes);
                var decrypted = Asymmetric.DecryptRSA(asymetricKey.Private, encrypted);
                if (decrypted.GetString() != message)
                {
                    Console.WriteLine("ERROR: Encryption Failed");
                    return;
                }
            }
            timer.Stop();

            var asymetricTime = timer.ElapsedMilliseconds;

            Console.WriteLine("Symmetric Encryption took {0} ms to encrypt and decrypt 100 times", symmetricTime);
            Console.WriteLine("Asymmetric Encryption took {0} ms to encrypt and decrypt 100 times", asymetricTime);
        }
Example #28
0
        public async Task TestSeveralWriteRoutines()
        {
            var clientConfig = new Config
            {
                KeyPair              = Asymmetric.GenerateKeyPair(),
                HandshakePattern     = NoiseHandshakeType.NoiseXX,
                StaticPublicKeyProof = new byte[] { },
                PublicKeyVerifier    = ConnectionTest.Verifier
            };

            var serverConfig = new Config
            {
                KeyPair              = Asymmetric.GenerateKeyPair(),
                HandshakePattern     = NoiseHandshakeType.NoiseXX,
                StaticPublicKeyProof = new byte[] { },
                PublicKeyVerifier    = ConnectionTest.Verifier
            };

            await this.RunConnectionTest(clientConfig, serverConfig, 1810);
        }
Example #29
0
        private void PrepareDisco(int port)
        {
            // init
            var clientConfig = new Config
            {
                KeyPair          = Asymmetric.GenerateKeyPair(),
                HandshakePattern = NoiseHandshakeType.NoiseNK
            };

            var serverConfig = new Config
            {
                KeyPair          = Asymmetric.GenerateKeyPair(),
                HandshakePattern = NoiseHandshakeType.NoiseNK
            };

            // set up remote keys
            serverConfig.RemoteKey = clientConfig.KeyPair.PublicKey;
            clientConfig.RemoteKey = serverConfig.KeyPair.PublicKey;
            this.PrepareDiscoServer(serverConfig, port);
            System.Threading.Thread.Sleep(5000);
            this.PrepareDiscoClient(clientConfig, port);
        }
Example #30
0
        public async Task TestHalfDuplex()
        {
            // init
            var clientConfig = new Config
            {
                KeyPair              = Asymmetric.GenerateKeyPair(),
                HandshakePattern     = NoiseHandshakeType.NoiseXX,
                PublicKeyVerifier    = ConnectionTest.Verifier,
                StaticPublicKeyProof = new byte[] { },
                HalfDuplex           = true
            };

            var serverConfig = new Config
            {
                KeyPair              = Asymmetric.GenerateKeyPair(),
                HandshakePattern     = NoiseHandshakeType.NoiseXX,
                PublicKeyVerifier    = ConnectionTest.Verifier,
                StaticPublicKeyProof = new byte[] { },
                HalfDuplex           = true
            };

            await this.RunConnectionTest(clientConfig, serverConfig, 1811, 10);
        }
Example #31
0
        static void RunBasicScenario(string message, bool fileOutput = false, string filePath = null)
        {
            if (fileOutput)
            {
                if (filePath == null)
                {
                    filePath = Directory.GetCurrentDirectory() + @"\BasicScenario.txt";
                }

                Output.SetFileOutPut(filePath);
            }

            var messageBytes = message.GetBytes();

            Console.WriteLine("Begining basic scenario with message");
            Console.WriteLine(message);
            WriteByteArray(messageBytes);
            WriteGap();

            var hash = message.GetHash(HashTypes.SHALE);

            Console.WriteLine("Hash computed");
            WriteByteArray(hash);
            WriteGap();

            var aliceKeys = Asymmetric.GenerateRSAKeys();
            var bobKeys   = Asymmetric.GenerateRSAKeys();

            Console.WriteLine("RSA keys generated");
            Console.WriteLine("Alice: \n{0}", aliceKeys);
            Console.WriteLine("Bob: \n{0}", bobKeys);
            WriteGap();

            var encryptedHash = Asymmetric.EncryptRSA(aliceKeys.Private, hash);

            Console.WriteLine("Hash encrypted with Alice's private Key");
            WriteByteArray(encryptedHash);
            WriteGap();

            var augmentedMessage = Helper.CombineByteArrays(messageBytes, encryptedHash);

            Console.WriteLine("Combined original message and encrypted hash.");
            WriteByteArray(augmentedMessage);
            WriteGap();

            var DES3Key = Symmetric.Generate3DESKey();

            Console.WriteLine("DES3 Key Generated");
            WriteByteArray(DES3Key);
            WriteGap();

            var encryptedMessage = Symmetric.Encrypt3DES(DES3Key, augmentedMessage);

            Console.WriteLine("Combined message encrypted with DES3 encryption");
            WriteByteArray(encryptedMessage);
            WriteGap();

            var encryptedKey = Asymmetric.EncryptRSA(bobKeys.Public, DES3Key);

            Console.WriteLine("DES3 Encrypted with bob's public key");
            WriteByteArray(encryptedKey);
            WriteGap();

            var transmissionMessage = Helper.CombineByteArrays(encryptedMessage, encryptedKey);

            Console.WriteLine("Encrypted Message and encrypted session key combined for transmission");
            WriteByteArray(encryptedKey);
            WriteGap();

            /** --------------------------------------------------------------------------------------- **/

            Console.WriteLine("Simulating Transmission");
            Console.Write("[");
            Console.CursorLeft = 21;
            Console.Write("]");
            Console.CursorLeft = 1;
            for (var i = 0; i < 20; i++)
            {
                Console.Write("-");
                Thread.Sleep(100);
            }
            WriteGap();

            /** --------------------------------------------------------------------------------------- **/

            var recoveredEncryptedKey = new byte[30];
            var recoveredCipherText   = new byte[transmissionMessage.Length - recoveredEncryptedKey.Length];

            SplitMessage(ref recoveredEncryptedKey, ref recoveredCipherText, transmissionMessage);

            Console.WriteLine("Split transmission message into key and ciphertext\n");
            Console.WriteLine("Key");
            WriteByteArray(recoveredEncryptedKey);
            Console.WriteLine();
            Console.WriteLine("Ciphertext");
            WriteByteArray(recoveredCipherText);
            WriteGap();

            var decrypedDES3Key = Asymmetric.DecryptRSA(bobKeys.Private, recoveredEncryptedKey);

            Console.WriteLine("Decrypted DES3 key using bob's private key");
            WriteByteArray(decrypedDES3Key);
            WriteGap();

            var decryptedMessage = Symmetric.Decrypt3DES(decrypedDES3Key, recoveredCipherText);

            Console.WriteLine("Decrypted ciphertext using decrypted DES3 Key");
            WriteByteArray(decryptedMessage);
            WriteGap();

            var recoveredSignature = new byte[5];
            var recoveredMessage   = new byte[decryptedMessage.Length - recoveredSignature.Length];

            SplitMessage(ref recoveredSignature, ref recoveredMessage, decryptedMessage);

            Console.WriteLine("Split ciphertext into message and signature\n");
            Console.WriteLine("Message");
            WriteByteArray(recoveredMessage);
            Console.WriteLine();
            Console.WriteLine("signature");
            WriteByteArray(recoveredSignature);
            WriteGap();

            var decryptedHash = Asymmetric.DecryptRSA(aliceKeys.Public, recoveredSignature);

            Console.WriteLine("Signature decrypted uusing alice's public key");
            WriteByteArray(decryptedHash);
            WriteGap();

            var recoveredMessageHash = recoveredMessage.GetString().GetHash(HashTypes.SHALE);

            Console.WriteLine("Compare two hashes\n");
            Console.WriteLine("Generated by sender");
            WriteByteArray(decryptedHash);
            Console.WriteLine();
            Console.WriteLine("Generated by reciever");
            WriteByteArray(recoveredMessageHash);
            WriteGap();

            if (decryptedHash.SequenceEqual(recoveredMessageHash))
            {
                Console.WriteLine("Hashes are identical");
                Console.WriteLine("This means we can be sure the message is from Alice and was unaltered");
            }
            else
            {
                Console.WriteLine("Hashes are different");
                Console.WriteLine("This means either the message was not from Alice, or it was altered during transmission");
            }

            Output.Dispose();
        }