public byte[] GetVerifiedSharedPart(byte[] securePart)
        {
            if (securePart.Length < 4)
            {
                throw new ArgumentException("Signed part was too short");
            }

            // Read lengths
            ushort publicLength = (ushort)(((ushort)securePart[0]) | ((ushort)securePart[1] << 8));
            ushort proofLength  = (ushort)(((ushort)securePart[2]) | ((ushort)securePart[3] << 8));

            if (securePart.Length != publicLength + proofLength + (sizeof(ushort) * 2))
            {
                throw new CryptographicException("Part lengths did not match");
            }

            // Alloc parts
            byte[] publicPart = new byte[publicLength];
            byte[] proofPart  = new byte[proofLength];

            // Copy parts
            Buffer.BlockCopy(securePart, sizeof(ushort) * 2, publicPart, 0, publicLength);
            Buffer.BlockCopy(securePart, sizeof(ushort) * 2 + publicLength, proofPart, 0, proofLength);

            if (_isSigner)
            {
                using (SHA256Managed sha = new SHA256Managed())
                {
                    byte[] claimedHash = _rsa.Decrypt(proofPart, false);
                    byte[] realHash    = sha.ComputeHash(publicPart);

                    // Prevent timing attacks by using constant time
                    if (ComparisonUtils.ConstTimeArrayEqual(claimedHash, realHash))
                    {
                        return(_diffieHellanInstance.GetSharedSecretRaw(publicPart));
                    }
                    else
                    {
                        throw new CryptographicException("Hash did not match the signed hash");
                    }
                }
            }
            else
            {
                using (SHA256Managed sha = new SHA256Managed())
                {
                    if (_rsa.VerifyData(publicPart, sha, proofPart))
                    {
                        return(_diffieHellanInstance.GetSharedSecretRaw(publicPart));
                    }
                    else
                    {
                        throw new CryptographicException("Signature was invalid");
                    }
                }
            }
        }
示例#2
0
        public static void RunECDHE(int iterations)
        {
            Console.WriteLine("Running " + iterations + " diffie hellman key exchanges");

            Stopwatch watch = new Stopwatch();

            for (int i = 0; i < iterations; i++)
            {
                watch.Start();

                // Both create their instances
                ECDiffieHellman serverDiffie = new ECDiffieHellman();
                ECDiffieHellman clientDiffie = new ECDiffieHellman();

                // Exchange publics

                /* START TRANSMISSION */
                byte[] serverPublic = serverDiffie.GetPublicKey();
                byte[] clientPublic = clientDiffie.GetPublicKey();
                /* END TRANSMISSION */

                // Calculate shared
                byte[] key1 = serverDiffie.GetSharedSecretRaw(clientPublic);
                byte[] key2 = clientDiffie.GetSharedSecretRaw(serverPublic);

                watch.Stop();

                if (key1.Length != key2.Length)
                {
                    Console.WriteLine("CRITICAL: LENGTH MISSMATCH");
                    continue;
                }

                for (int x = 0; x < key1.Length; x++)
                {
                    if (key1[x] != key2[x])
                    {
                        Console.WriteLine("CRITICAL: MISSMATCH");
                        break;
                    }
                }
            }

            Console.WriteLine("Completed in " + watch.ElapsedMilliseconds + " ms, " + (watch.ElapsedMilliseconds / iterations) + " ms per exchange");
        }