package org.encryptor4j.test; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.SecureRandom; import java.security.Security; import org.encryptor4j.DHPeer; import org.encryptor4j.ECDHPeer; import org.encryptor4j.KeyAgreementPeer; import static org.junit.Assert.*; import org.junit.Test; /** * <p>Unit test that tests key agreement algorithms such as Diffie-Hellman and Elliptic Curve Diffie-Hellman.</p> * <p><b>Note:</b> This unit test does not contain MQV and ECMQV test methods because these algorithms are considered insecure and thus obsolete.</p> * * @see https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange * @see https://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman * @see https://en.wikipedia.org/wiki/MQV * @author Martin * */ public class KeyAgreementTest { static { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } /** * <p>Tests Diffie-Hellman key exchange.</p> * <p>Use at least a <code>p</code> of 2048 bits. Better pre-determined values for <code>p</code> can be found at the link below.</p> * @see https://tools.ietf.org/html/rfc3526 * @throws GeneralSecurityException */ @Test public void testDH() throws GeneralSecurityException { // Create primes p & g // Tip: You don't need to regenerate p; Use a fixed value in your application int bits = 2048; BigInteger p = BigInteger.probablePrime(bits, new SecureRandom()); BigInteger g = new BigInteger("2"); // Create two peers KeyAgreementPeer peerA = new DHPeer(p, g); KeyAgreementPeer peerB = new DHPeer(p, g); // Exchange public keys and compute shared secret byte[] sharedSecretA = peerA.computeSharedSecret(peerB.getPublicKey()); byte[] sharedSecretB = peerB.computeSharedSecret(peerA.getPublicKey()); assertArrayEquals(sharedSecretA, sharedSecretB); } @Test public void testECDH() throws GeneralSecurityException { String algorithm = "brainpoolp512r1"; // Create two peers KeyAgreementPeer peerA = new ECDHPeer(algorithm); KeyAgreementPeer peerB = new ECDHPeer(algorithm); // Exchange public keys and compute shared secret byte[] sharedSecretA = peerA.computeSharedSecret(peerB.getPublicKey()); byte[] sharedSecretB = peerB.computeSharedSecret(peerA.getPublicKey()); assertArrayEquals(sharedSecretA, sharedSecretB); } // MQV and ECMQV are not safe! /*@Test public void testECMQV() throws GeneralSecurityException { String algorithm = "brainpoolp512r1"; // Create two peers KeyAgreementPeer peerA = new ECMQVPeer(algorithm); KeyAgreementPeer peerB = new ECMQVPeer(algorithm); // Exchange public keys and compute shared secret byte[] sharedSecretA = peerA.computeSharedSecret(peerB.getPublicKey()); byte[] sharedSecretB = peerB.computeSharedSecret(peerA.getPublicKey()); assertArrayEquals(sharedSecretA, sharedSecretB); }*/ }