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"); } } } }
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"); }