Ejemplo n.º 1
0
 public static byte[] Sha256Digest(this byte[] bytes)
 {
     Org.BouncyCastle.Crypto.Digests.Sha256Digest myHash = new Org.BouncyCastle.Crypto.Digests.Sha256Digest();
     myHash.BlockUpdate(bytes, 0, bytes.Length);
     byte[] compArr = new byte[myHash.GetDigestSize()];
     myHash.DoFinal(compArr, 0);
     return(compArr);
 }
Ejemplo n.º 2
0
        public static byte[] SHA256(string text)
        {
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(text);

            Org.BouncyCastle.Crypto.Digests.Sha256Digest digester = new Org.BouncyCastle.Crypto.Digests.Sha256Digest();
            byte[] retValue = new byte[digester.GetDigestSize()];
            digester.BlockUpdate(bytes, 0, bytes.Length);
            digester.DoFinal(retValue, 0);
            return(retValue);
        }
Ejemplo n.º 3
0
 public static byte[] SimpleHash(byte[] data, byte[] addition = null)
 {
     Org.BouncyCastle.Crypto.Digests.Sha256Digest myHash = new Org.BouncyCastle.Crypto.Digests.Sha256Digest();
     myHash.BlockUpdate(data, 0, data.Length);
     if (addition != null)
     {
         myHash.BlockUpdate(addition, 0, addition.Length);
     }
     byte[] compArr = new byte[myHash.GetDigestSize()];
     myHash.DoFinal(compArr, 0);
     return(compArr);
 }
        /// <summary>
        /// Calculate a SHA-256 digest (hash).
        /// </summary>
        /// <param name="data">The data to be hashed.</param>
        /// <returns>A byte array that contains the calculated hash value.</returns>
        static protected byte[] Sha256Digest(byte[] data)
        {
            var hasher = new Org.BouncyCastle.Crypto.Digests.Sha256Digest();

            hasher.BlockUpdate(data, 0, data.Length);

            var digest = new byte[hasher.GetDigestSize()];

            hasher.DoFinal(digest, 0);

            return(digest);
        }
Ejemplo n.º 5
0
        protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm)
        {
            System.Console.WriteLine(data);

            return(data);

            // byte[] data = System.Text.Encoding.UTF8.GetBytes(text);

            Org.BouncyCastle.Crypto.Digests.Sha256Digest digester = new Org.BouncyCastle.Crypto.Digests.Sha256Digest();
            byte[] retValue = new byte[digester.GetDigestSize()];
            digester.BlockUpdate(data, 0, data.Length);
            digester.DoFinal(retValue, 0);
            return(retValue);
        }
Ejemplo n.º 6
0
        private string CreateSHA256Hash(string data)
        {
            var encData = Encoding.UTF8.GetBytes(data);

            Org.BouncyCastle.Crypto.Digests.Sha256Digest myHash = new Org.BouncyCastle.Crypto.Digests.Sha256Digest();
            myHash.BlockUpdate(encData, 0, encData.Length);
            byte[] compArr = new byte[myHash.GetDigestSize()];
            myHash.DoFinal(compArr, 0);
            StringBuilder result = new StringBuilder();

            for (int i = 0; i < compArr.Length; i++)
            {
                result.Append(compArr[i].ToString("X2"));
            }
            return(result.ToString());
        }
Ejemplo n.º 7
0
 public byte[] GetHash()
 {
     byte[] handshakeHash;
     if (_VerifyHandshake == null)
     {
         IDigest sha1 = new Org.BouncyCastle.Crypto.Digests.Sha1Digest(_VerifyHandshakeSHA1);
         IDigest md5  = new Org.BouncyCastle.Crypto.Digests.MD5Digest(_VerifyHandshakeMD5);
         handshakeHash = new byte[sha1.GetDigestSize() + md5.GetDigestSize()];
         md5.DoFinal(handshakeHash, 0);
         sha1.DoFinal(handshakeHash, md5.GetDigestSize());
     }
     else
     {
         IDigest hash = new Org.BouncyCastle.Crypto.Digests.Sha256Digest((Org.BouncyCastle.Crypto.Digests.Sha256Digest)_VerifyHandshake);
         handshakeHash = new byte[hash.GetDigestSize()];
         hash.DoFinal(handshakeHash, 0);
     }
     return(handshakeHash);
 }
        /// <summary>
        /// Retrieve the JWK Thumbprint of this key.
        /// </summary>
        /// <returns>A byte array of the calculated thumbprint digest.</returns>
        public byte[] Thumbprint()
        {
            if (KeyType == JWK.KeyType.RSA)
            {
                var hasher = new Org.BouncyCastle.Crypto.Digests.Sha256Digest();

                var JWK = new Dictionary <string, string>
                {
                    { "e", Exponent },
                    { "kty", KeyType },
                    { "n", Modulus }
                };

                var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(JWK, Formatting.None));
                hasher.BlockUpdate(bytes, 0, bytes.Length);

                var digest = new byte[hasher.GetDigestSize()];
                hasher.DoFinal(digest, 0);

                return(digest);
            }

            throw new NotSupportedException("Unknown JWK key type.");
        }
Ejemplo n.º 9
0
        static void Main(string[] args)
        {
            int    messageCount     = 1000000;
            double clientDropChance = 0.0;
            double serverDropChance = 0.0;
            var    defaultServices  = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());

            Random r = new Random();
            RandomNumberGenerator rng = new RandomNumberGenerator();
            Stopwatch             sw  = new Stopwatch();

            Console.WriteLine("Generating data...");
            byte[] keys   = new byte[16 * 1000000];
            byte[] blocks = new byte[16 * 1000000];
            byte[] output = new byte[32 * 1000000];
            rng.Generate(keys);
            rng.Generate(blocks);

            Thread.Sleep(1000);
            {
                var poly = new Poly(defaultServices.AesFactory);
                poly.Init(new ArraySegment <byte>(keys, 0, 32), new ArraySegment <byte>(blocks, 0, 16), 16);
                poly.Init(new ArraySegment <byte>(keys, 1000, 32), new ArraySegment <byte>(blocks, 1000, 16), 16);
                Console.WriteLine("Doing Pol1305 MACs");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < keys.Length; i += 32)
                {
                    poly.Process(blocks, i, 16);
                    poly.Process(blocks, i, 16);
                    poly.Process(blocks, i, 16);
                    poly.Process(blocks, i, 16);
                    poly.Compute(new ArraySegment <byte>(output, i, 16));
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 32) / sw.Elapsed.TotalSeconds:F0}/s)");
            }
            Thread.Sleep(1000);
            {
                var sha = System.Security.Cryptography.SHA256.Create();
                sha.ComputeHash(blocks, 10000, 16);
                Console.WriteLine("Doing SHA256 hashes (dotnet)");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < blocks.Length; i += 16)
                {
                    sha.ComputeHash(blocks, i, 16);
                }

                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }
            Thread.Sleep(1000);
            {
                var sha = new Org.BouncyCastle.Crypto.Digests.Sha256Digest();
                sha.BlockUpdate(blocks, 10000, 16);
                sha.DoFinal(output, 10000);
                Console.WriteLine("Doing SHA256 hashes (bc)");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < blocks.Length; i += 16)
                {
                    sha.BlockUpdate(blocks, i, 16);
                    sha.DoFinal(output, i * 2);
                }

                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }

            Thread.Sleep(1000);
            {
                var aes = System.Security.Cryptography.Aes.Create();
                aes.Mode = System.Security.Cryptography.CipherMode.ECB;
                var key = new byte[16];
                Array.Copy(keys, 10000, key, 0, 16);
                aes.CreateEncryptor(key, null);
                Console.WriteLine("Calculating AES keys (dotnet)");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < keys.Length; i += 16)
                {
                    Array.Copy(keys, i, key, 0, 16);
                    aes.CreateEncryptor(key, null);
                }

                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }
            Thread.Sleep(1000);
            {
                var aes = System.Security.Cryptography.Aes.Create();
                aes.Mode = System.Security.Cryptography.CipherMode.ECB;
                var key = new byte[16];
                Array.Copy(keys, key, 16);
                var enc = aes.CreateEncryptor(key, null);
                enc.TransformBlock(blocks, 10000, 16, output, 10000);
                Console.WriteLine("Processing AES blocks (dotnet");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < blocks.Length; i += 16)
                {
                    enc.TransformBlock(blocks, i, 16, output, i);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }
            Thread.Sleep(1000);
            {
                Org.BouncyCastle.Crypto.Engines.AesEngine aes = new Org.BouncyCastle.Crypto.Engines.AesEngine();
                aes.Init(true, new KeyParameter(keys, 10000, 16));
                aes.Init(true, new KeyParameter(keys, 20000, 16));
                Console.WriteLine("Calculating AES keys (bc)");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < keys.Length; i += 16)
                {
                    aes.Init(true, new KeyParameter(keys, i, 16));
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }
            Thread.Sleep(1000);
            {
                Org.BouncyCastle.Crypto.Engines.AesEngine aes = new Org.BouncyCastle.Crypto.Engines.AesEngine();
                aes.Init(true, new KeyParameter(keys, 12300, 16));
                aes.ProcessBlock(blocks, 10000, output, 10000);
                Console.WriteLine("Processing AES blocks (bc)");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < blocks.Length; i += 16)
                {
                    aes.ProcessBlock(blocks, i, output, i);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }
            Thread.Sleep(1000);
            {
                var aes = new Org.BouncyCastle.Crypto.Engines.AesLightEngine();
                aes.Init(true, new KeyParameter(keys, 10000, 16));
                aes.Init(true, new KeyParameter(keys, 20000, 16));
                Console.WriteLine("Calculating AES keys (bc light)");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < keys.Length; i += 16)
                {
                    aes.Init(true, new KeyParameter(keys, i, 16));
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }
            Thread.Sleep(1000);
            {
                var aes = new Org.BouncyCastle.Crypto.Engines.AesLightEngine();
                aes.Init(true, new KeyParameter(keys, 12340, 16));
                aes.ProcessBlock(blocks, 10000, output, 10000);
                Console.WriteLine("Processing AES blocks (bc light)");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < blocks.Length; i += 16)
                {
                    aes.ProcessBlock(blocks, i, output, i);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }

            Thread.Sleep(1000);
            {
                SymmetricRacthet sr = new SymmetricRacthet();
                var(client, server) = CreateAndInitialize();
                var kdf = new AesKdf(client.Services.AesFactory);
                sr.Initialize(rng.Generate(32));
                Console.WriteLine("Testing Symmetric Ratchet Speed");
                sr.RatchetForSending(kdf);
                sr.RatchetForSending(kdf);
                sr.RatchetForSending(kdf);
                sr.RatchetForSending(kdf);
                sw.Reset();
                sw.Start();
                int cnt = 1000000;
                for (int i = 0; i < cnt; i++)
                {
                    sr.RatchetForSending(kdf);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({cnt / sw.Elapsed.TotalSeconds:F0}/s)");
                Console.WriteLine($"It would take { (double)int.MaxValue / 2 / (cnt / sw.Elapsed.TotalSeconds) / 60:F0} minutes to do 2^32 ratchets");
            }

            Thread.Sleep(1000);
            {
                Console.WriteLine("Testing one way message send speed (small: 16 bytes)...");
                var(client, server) = CreateAndInitialize();
                var messagesToSend = Enumerable.Range(0, messageCount).Select(_ => rng.Generate(16)).ToArray();
                var messagesSent   = new List <byte[]>(messageCount);
                var m1             = client.Send(new byte[16]);
                var m2             = client.Send(new byte[16]);
                var m3             = client.Send(new byte[16]);
                sw.Reset();
                sw.Start();
                for (int i = 0; i < messageCount; i++)
                {
                    messagesSent.Add(client.Send(messagesToSend[i]));
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({messageCount / sw.Elapsed.TotalSeconds:F0}/s)");
                Console.WriteLine($"Bandwidth: { messagesToSend.Sum(x => x.Length * 8) / sw.Elapsed.TotalSeconds / (1024 * 1024):F0} Mbps");


                Thread.Sleep(1000);
                Console.WriteLine("Testing one way message receive speed (small: 16 bytes)...");
                server.Receive(m1);
                server.Receive(m2);
                server.Receive(m3);
                sw.Reset();
                sw.Start();
                for (int i = 0; i < messageCount; i++)
                {
                    server.Receive(messagesSent[i]);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({messageCount / sw.Elapsed.TotalSeconds:F0}/s)");
                Console.WriteLine($"Bandwidth: { messagesToSend.Sum(x => x.Length * 8) / sw.Elapsed.TotalSeconds / (1024 * 1024):F0} Mbps");
            }

            Thread.Sleep(2000);
            {
                Console.WriteLine("Testing one way message send speed (large: 64 bytes)...");
                var(client, server) = CreateAndInitialize();
                var messagesToSend = Enumerable.Range(0, messageCount).Select(_ => rng.Generate(64)).ToArray();
                var messagesSent   = new List <byte[]>(messageCount);
                var m1             = client.Send(new byte[16]);
                var m2             = client.Send(new byte[16]);
                var m3             = client.Send(new byte[16]);
                sw.Reset();
                sw.Start();
                for (int i = 0; i < messageCount; i++)
                {
                    messagesSent.Add(client.Send(messagesToSend[i]));
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({messageCount / sw.Elapsed.TotalSeconds:F0}/s)");
                Console.WriteLine($"Bandwidth: { messagesToSend.Sum(x => x.Length * 8) / sw.Elapsed.TotalSeconds / (1024 * 1024):F0} Mbps");


                Thread.Sleep(1000);
                Console.WriteLine("Testing one way message receive speed (large: 64 bytes)...");
                server.Receive(m1);
                server.Receive(m2);
                server.Receive(m3);
                sw.Reset();
                sw.Start();
                for (int i = 0; i < messageCount; i++)
                {
                    server.Receive(messagesSent[i]);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({messageCount / sw.Elapsed.TotalSeconds:F0}/s)");
                Console.WriteLine($"Bandwidth: { messagesToSend.Sum(x => x.Length * 8) / sw.Elapsed.TotalSeconds / (1024 * 1024):F0} Mbps");
            }

            messageCount /= 10;
            Thread.Sleep(2000);
            {
                Console.WriteLine("Testing one way message send speed (IP: 1350 bytes)...");
                var(client, server) = CreateAndInitialize(1350);
                var messagesToSend = Enumerable.Range(0, messageCount).Select(_ => rng.Generate(1300)).ToArray();
                var messagesSent   = new List <byte[]>(messageCount);
                var m1             = client.Send(new byte[16]);
                var m2             = client.Send(new byte[16]);
                var m3             = client.Send(new byte[16]);
                sw.Reset();
                sw.Start();
                for (int i = 0; i < messageCount; i++)
                {
                    messagesSent.Add(client.Send(messagesToSend[i]));
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({messageCount / sw.Elapsed.TotalSeconds:F0}/s)");
                Console.WriteLine($"Bandwidth: { messagesToSend.Sum(x => x.Length * 8) / sw.Elapsed.TotalSeconds / (1024 * 1024):F0} Mbps");


                Thread.Sleep(1000);
                Console.WriteLine("Testing one way message receive speed (IP: 1350 bytes)...");
                server.Receive(m1);
                server.Receive(m2);
                server.Receive(m3);
                sw.Reset();
                sw.Start();
                for (int i = 0; i < messageCount; i++)
                {
                    server.Receive(messagesSent[i]);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({messageCount / sw.Elapsed.TotalSeconds:F0}/s)");
                Console.WriteLine($"Bandwidth: { messagesToSend.Sum(x => x.Length * 8) / sw.Elapsed.TotalSeconds / (1024 * 1024):F0} Mbps");
            }

            Thread.Sleep(1000);
            {
                Console.WriteLine("Testing ECDHratchet speed...");
                var(client, server) = CreateAndInitialize(1350);
                var messagesToSend = Enumerable.Range(0, messageCount / 4000).Select(_ => rng.Generate(32)).ToArray();
                server.Receive(client.Send(new byte[32]));
                client.Receive(server.Send(new byte[32]));
                sw.Reset();
                sw.Start();
                for (int i = 0; i < messageCount / 4000; i++)
                {
                    var m1 = client.Send(messagesToSend[i]);
                    server.Receive(m1);
                    var m2 = server.Send(messagesToSend[i]);
                    client.Receive(m2);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(messageCount / 2000) / sw.Elapsed.TotalSeconds:F0}/s)");
            }

            messageCount *= 10;
            Thread.Sleep(1000);
            {
                var(client, server) = CreateAndInitialize();
                var              clientMessages           = new HashSet <byte[]>(Enumerable.Range(0, messageCount).Select(_ => rng.Generate(32)));
                var              serverMessages           = new HashSet <byte[]>(Enumerable.Range(0, messageCount).Select(_ => rng.Generate(32)));
                Queue <byte[]>   clientMessagesToSend     = new Queue <byte[]>(clientMessages);
                Queue <byte[]>   serverMessagesToSend     = new Queue <byte[]>(serverMessages);
                var              messagesSentFromClient   = new Queue <byte[]>();
                var              messagesSentFromServer   = new Queue <byte[]>();
                HashSet <byte[]> messagesReceivedByClient = new HashSet <byte[]>();
                HashSet <byte[]> messagesReceivedByServer = new HashSet <byte[]>();

                byte[] DoubleInSize(byte[] payload) => payload.Concat(payload).ToArray();

                int clientSent = 0, serverSent = 0, clientReceived = 0, serverReceived = 0, clientDropped = 0, serverDropped = 0;
                Console.WriteLine($"Sending {messageCount}/{clientDropChance:P0} and {messageCount}/{serverDropChance:P0}");

                sw.Reset();
                sw.Start();
                double oldTime = 0;
                int    oldCnt  = 0;
                for (int i = 0; ; i++)
                {
                    bool anyMessagesToReceive = messagesSentFromClient.TryPeek(out var _) || messagesSentFromServer.TryPeek(out var _);
                    bool anyMessagesToSend    = clientMessagesToSend.TryPeek(out var _) || serverMessagesToSend.TryPeek(out var _);
                    if (!anyMessagesToReceive && !anyMessagesToSend)
                    {
                        break;
                    }

                    if (i % 1000 == 0)
                    {
                        var totalReceived = clientReceived + serverReceived + clientDropped + serverDropped;
                        var totalAll      = messageCount + messageCount;
                        var percentage    = (double)totalReceived / totalAll;

                        var newTime   = sw.Elapsed.TotalSeconds;
                        var deltaTime = newTime - oldTime;
                        var deltaCnt  = totalReceived - oldCnt;

                        double perSecond = 0;
                        if (oldTime != 0)
                        {
                            perSecond = deltaCnt / deltaTime;
                        }
                        Console.Write($"\r{percentage:P0} - c: {clientSent}/{clientDropped} -> {serverReceived}  s: {serverSent}/{serverDropped} -> {clientReceived}   ({perSecond:F0}/s)  ");

                        oldCnt  = totalReceived;
                        oldTime = newTime;
                    }

                    var    clientOrServer = r.Next(2);
                    var    sendOrReceive  = r.Next(2);
                    double ratio          = (double)messageCount / messageCount;
                    int    maxClient      = 100;
                    int    maxServer      = (int)(100 / ratio);
                    var    maxMessages    = r.Next(clientOrServer == 0 ? maxClient : maxServer) + 1;

                    if (anyMessagesToSend && (sendOrReceive == 0 || !anyMessagesToReceive))
                    {
                        if (clientOrServer == 0) // send from client
                        {
                            while (maxMessages-- > 0)
                            {
                                clientMessagesToSend.TryDequeue(out var payload);
                                if (payload != null)
                                {
                                    payload = r.Next(10) > 7 ? DoubleInSize(payload) : payload;
                                    var message = client.Send(payload);
                                    if (r.NextDouble() > clientDropChance)
                                    {
                                        clientSent++;
                                        messagesSentFromClient.Enqueue(message);
                                    }
                                    else
                                    {
                                        clientDropped++;
                                    }
                                }
                            }
                        }
                        else
                        {
                            while (maxMessages-- > 0)
                            {
                                serverMessagesToSend.TryDequeue(out var payload);
                                if (payload != null)
                                {
                                    payload = r.Next(10) > 7 ? DoubleInSize(payload) : payload;
                                    var message = server.Send(payload);
                                    if (r.NextDouble() > serverDropChance)
                                    {
                                        serverSent++;
                                        messagesSentFromServer.Enqueue(message);
                                    }
                                    else
                                    {
                                        serverDropped++;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        if (clientOrServer != 0)  // receive by client
                        {
                            while (maxMessages-- > 0)
                            {
                                messagesSentFromServer.TryDequeue(out var message);
                                if (message != null)
                                {
                                    var payload = client.Receive(message).Payload;
                                    messagesReceivedByClient.Add(payload);
                                    clientReceived++;
                                }
                            }
                        }
                        else // receive by server
                        {
                            while (maxMessages-- > 0)
                            {
                                messagesSentFromClient.TryDequeue(out var message);
                                if (message != null)
                                {
                                    var payload = server.Receive(message).Payload;
                                    messagesReceivedByServer.Add(payload);
                                    serverReceived++;
                                }
                            }
                        }
                    }
                }

                Console.WriteLine("Done");
            }
        }
Ejemplo n.º 10
0
 public byte[] GetHash()
 {
     byte[] handshakeHash;
     if (_VerifyHandshake == null)
     {
         IDigest sha1 = new Org.BouncyCastle.Crypto.Digests.Sha1Digest(_VerifyHandshakeSHA1);
         IDigest md5 = new Org.BouncyCastle.Crypto.Digests.MD5Digest(_VerifyHandshakeMD5);
         handshakeHash = new byte[sha1.GetDigestSize() + md5.GetDigestSize()];
         md5.DoFinal(handshakeHash, 0);
         sha1.DoFinal(handshakeHash, md5.GetDigestSize());
     }
     else
     {
         IDigest hash = new Org.BouncyCastle.Crypto.Digests.Sha256Digest((Org.BouncyCastle.Crypto.Digests.Sha256Digest)_VerifyHandshake);
         handshakeHash = new byte[hash.GetDigestSize()];
         hash.DoFinal(handshakeHash, 0);
     }
     return handshakeHash;
 }
Ejemplo n.º 11
0
        /// <summary>
        ///   Creates a new signing key pair
        /// </summary>
        /// <param name="name">The name of the key or zone</param>
        /// <param name="recordClass">The record class of the DnsKeyRecord</param>
        /// <param name="timeToLive">The TTL in seconds to the DnsKeyRecord</param>
        /// <param name="flags">The Flags of the DnsKeyRecord</param>
        /// <param name="protocol">The protocol version</param>
        /// <param name="algorithm">The key algorithm</param>
        /// <param name="keyStrength">The key strength or 0 for default strength</param>
        /// <returns></returns>
        public static KeyPairRecord CreateSigningKey(DnsSecAlgorithm algorithm, DnsKeyFlags flags, int keyStrength = 0)
        {
            // Found in DnsKeyRecord.CreateSigningKey
            KeyPairRecord rec = new KeyPairRecord();

            rec.Flags     = flags;
            rec.Algorithm = algorithm;

            Org.BouncyCastle.Security.SecureRandom _secureRandom =
                new Org.BouncyCastle.Security.SecureRandom(new Org.BouncyCastle.Crypto.Prng.CryptoApiRandomGenerator());

            // https://csharp.hotexamples.com/examples/Org.BouncyCastle.Crypto.Generators/DsaKeyPairGenerator/GenerateKeyPair/php-dsakeypairgenerator-generatekeypair-method-examples.html

            switch (algorithm)
            {
            case DnsSecAlgorithm.RsaSha1:
            case DnsSecAlgorithm.RsaSha1Nsec3Sha1:
            case DnsSecAlgorithm.RsaSha256:
            case DnsSecAlgorithm.RsaSha512:
                if (keyStrength == 0)
                {
                    keyStrength = (flags == (DnsKeyFlags.Zone | DnsKeyFlags.SecureEntryPoint)) ? 2048 : 1024;
                }

                Org.BouncyCastle.Crypto.Generators.RsaKeyPairGenerator rsaKeyGen = new Org.BouncyCastle.Crypto.Generators.RsaKeyPairGenerator();
                rsaKeyGen.Init(new Org.BouncyCastle.Crypto.KeyGenerationParameters(_secureRandom, keyStrength));
                var rsaKey = rsaKeyGen.GenerateKeyPair();
                rec.KeyPair    = rsaKey;
                rec.PrivateKey = Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(rsaKey.Private).GetDerEncoded();
                var rsaPublicKey = (Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters)rsaKey.Public;
                var rsaExponent  = rsaPublicKey.Exponent.ToByteArrayUnsigned();
                var rsaModulus   = rsaPublicKey.Modulus.ToByteArrayUnsigned();

                int offset = 1;
                if (rsaExponent.Length > 255)
                {
                    rec.PublicKey = new byte[3 + rsaExponent.Length + rsaModulus.Length];
                    EncodeUShort(rec.PublicKey, ref offset, (ushort)rec.PublicKey.Length);
                }
                else
                {
                    rec.PublicKey    = new byte[1 + rsaExponent.Length + rsaModulus.Length];
                    rec.PublicKey[0] = (byte)rsaExponent.Length;
                }
                EncodeByteArray(rec.PublicKey, ref offset, rsaExponent);
                EncodeByteArray(rec.PublicKey, ref offset, rsaModulus);
                break;

            case DnsSecAlgorithm.Dsa:
            case DnsSecAlgorithm.DsaNsec3Sha1:
                if (keyStrength == 0)
                {
                    keyStrength = 1024;
                }

                Org.BouncyCastle.Crypto.Generators.DsaParametersGenerator dsaParamsGen = new Org.BouncyCastle.Crypto.Generators.DsaParametersGenerator();
                dsaParamsGen.Init(keyStrength, 12, _secureRandom);
                Org.BouncyCastle.Crypto.Generators.DsaKeyPairGenerator dsaKeyGen = new Org.BouncyCastle.Crypto.Generators.DsaKeyPairGenerator();
                dsaKeyGen.Init(new Org.BouncyCastle.Crypto.Parameters.DsaKeyGenerationParameters(_secureRandom, dsaParamsGen.GenerateParameters()));
                Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair dsaKey = dsaKeyGen.GenerateKeyPair();
                rec.KeyPair = dsaKey;

                rec.PrivateKey = Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(dsaKey.Private).GetDerEncoded();
                var dsaPublicKey = (Org.BouncyCastle.Crypto.Parameters.DsaPublicKeyParameters)dsaKey.Public;

                byte[] dsaY = dsaPublicKey.Y.ToByteArrayUnsigned();
                byte[] dsaP = dsaPublicKey.Parameters.P.ToByteArrayUnsigned();
                byte[] dsaQ = dsaPublicKey.Parameters.Q.ToByteArrayUnsigned();
                byte[] dsaG = dsaPublicKey.Parameters.G.ToByteArrayUnsigned();
                byte   dsaT = (byte)((dsaY.Length - 64) / 8);

                rec.PublicKey    = new byte[21 + 3 * dsaY.Length];
                rec.PublicKey[0] = dsaT;
                dsaQ.CopyTo(rec.PublicKey, 1);
                dsaP.CopyTo(rec.PublicKey, 21);
                dsaG.CopyTo(rec.PublicKey, 21 + dsaY.Length);
                dsaY.CopyTo(rec.PublicKey, 21 + 2 * dsaY.Length);
                break;

            case DnsSecAlgorithm.EccGost:
                Org.BouncyCastle.Crypto.Parameters.ECDomainParameters gostEcDomainParameters = Org.BouncyCastle.Asn1.CryptoPro.ECGost3410NamedCurves.GetByOid(Org.BouncyCastle.Asn1.CryptoPro.CryptoProObjectIdentifiers.GostR3410x2001CryptoProA);

                var gostKeyGen = new Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator();
                gostKeyGen.Init(new Org.BouncyCastle.Crypto.Parameters.ECKeyGenerationParameters(gostEcDomainParameters, _secureRandom));

                var gostKey = gostKeyGen.GenerateKeyPair();
                rec.KeyPair    = gostKey;
                rec.PrivateKey = Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(gostKey.Private).GetDerEncoded();
                var gostPublicKey = (Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters)gostKey.Public;

                rec.PublicKey = new byte[64];

                // gostPublicKey.Q.X.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, 32);
                gostPublicKey.Q.AffineXCoord.ToBigInteger().ToByteArrayUnsigned().CopyTo(rec.PublicKey, 32);
                // gostPublicKey.Q.Y.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, 0);
                gostPublicKey.Q.AffineYCoord.ToBigInteger().ToByteArrayUnsigned().CopyTo(rec.PublicKey, 0);

                System.Array.Reverse(rec.PublicKey);
                break;

            case DnsSecAlgorithm.EcDsaP256Sha256:
            case DnsSecAlgorithm.EcDsaP384Sha384:
                int ecDsaDigestSize;
                Org.BouncyCastle.Asn1.X9.X9ECParameters ecDsaCurveParameter;

                if (algorithm == DnsSecAlgorithm.EcDsaP256Sha256)
                {
                    ecDsaDigestSize     = new Org.BouncyCastle.Crypto.Digests.Sha256Digest().GetDigestSize();
                    ecDsaCurveParameter = Org.BouncyCastle.Asn1.Nist.NistNamedCurves.GetByOid(Org.BouncyCastle.Asn1.Sec.SecObjectIdentifiers.SecP256r1);
                }
                else
                {
                    ecDsaDigestSize     = new Org.BouncyCastle.Crypto.Digests.Sha384Digest().GetDigestSize();
                    ecDsaCurveParameter = Org.BouncyCastle.Asn1.Nist.NistNamedCurves.GetByOid(Org.BouncyCastle.Asn1.Sec.SecObjectIdentifiers.SecP384r1);
                }

                Org.BouncyCastle.Crypto.Parameters.ECDomainParameters ecDsaP384EcDomainParameters = new Org.BouncyCastle.Crypto.Parameters.ECDomainParameters(
                    ecDsaCurveParameter.Curve,
                    ecDsaCurveParameter.G,
                    ecDsaCurveParameter.N,
                    ecDsaCurveParameter.H,
                    ecDsaCurveParameter.GetSeed());

                var ecDsaKeyGen = new Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator();
                ecDsaKeyGen.Init(new Org.BouncyCastle.Crypto.Parameters.ECKeyGenerationParameters(ecDsaP384EcDomainParameters, _secureRandom));

                Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair ecDsaKey = ecDsaKeyGen.GenerateKeyPair();
                rec.KeyPair = ecDsaKey;

                rec.PrivateKey = Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(ecDsaKey.Private).GetDerEncoded();
                var ecDsaPublicKey = (Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters)ecDsaKey.Public;

                rec.PublicKey = new byte[ecDsaDigestSize * 2];
                // ecDsaPublicKey.Q.X.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, 0);
                ecDsaPublicKey.Q.AffineXCoord.ToBigInteger().ToByteArrayUnsigned().CopyTo(rec.PublicKey, 0);
                // ecDsaPublicKey.Q.Y.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, ecDsaDigestSize);
                ecDsaPublicKey.Q.AffineYCoord.ToBigInteger().ToByteArrayUnsigned().CopyTo(rec.PublicKey, ecDsaDigestSize);
                break;

            default:
                throw new System.NotSupportedException();
            }

            // return new DnsKeyRecord(name, recordClass, timeToLive, flags, protocol, algorithm, rec.PublicKey, rec.PrivateKey);
            return(rec);
        }