Skip to content

Instantly share code, notes, and snippets.

@mhberryman
Created September 6, 2015 19:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mhberryman/f22b3668e6b08e1fbfbc to your computer and use it in GitHub Desktop.
Save mhberryman/f22b3668e6b08e1fbfbc to your computer and use it in GitHub Desktop.
A simple script to play with Diffie-Hellman key exchange
import java.math.BigInteger;
import java.security.AlgorithmParameterGenerator;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import javax.crypto.KeyAgreement;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import javax.xml.bind.DatatypeConverter;
/**
* A simple test program that mimics interaction of client and server
* in a Diffie-Hellman key agreement with X.509 format.
*
* @author Mark Haydn Berryman
*/
public class testDH {
public static void main(String[] args) {
try {
/////////////////////////////// Server generates spec and sends to client
AlgorithmParameterGenerator servAPG = AlgorithmParameterGenerator.getInstance("DH");
servAPG.init(512);
DHParameterSpec servParamSpec = servAPG.generateParameters().getParameterSpec(DHParameterSpec.class);
BigInteger servp = servParamSpec.getP();
BigInteger servg = servParamSpec.getG();
System.out.println("P:" + servp + "\nG:" + servg);
/////////////////////////////// Client recieves p & g and creates spec
BigInteger clip = servp;
BigInteger clig = servg;
DHParameterSpec cliParamSpec = new DHParameterSpec(clip, clig);
/////////////////////////////// Server generates keypair
KeyPairGenerator servKPG = KeyPairGenerator.getInstance("DH");
servKPG.initialize(servParamSpec);
KeyPair servKP = servKPG.generateKeyPair();
String servPub = byteToHex(servKP.getPublic().getEncoded());
System.out.println("Server PKI:" + servPub);
/////////////////////////////// Client generates keypair
KeyPairGenerator cliKPG = KeyPairGenerator.getInstance("DH");
cliKPG.initialize(cliParamSpec);
KeyPair cliKP = cliKPG.generateKeyPair();
String cliPub = byteToHex(cliKP.getPublic().getEncoded());
System.out.println("Client PKI:" + cliPub);
/////////////////////////////// PKI exchange and convert back
DHPublicKey servCliPub = (DHPublicKey) KeyFactory.getInstance("DH").generatePublic(
new X509EncodedKeySpec(hexToByte(cliPub)));
DHPublicKey cliServPub = (DHPublicKey) KeyFactory.getInstance("DH").generatePublic(
new X509EncodedKeySpec(hexToByte(servPub)));
/////////////////////////////// Server generates secret
KeyAgreement servKA = KeyAgreement.getInstance("DH");
servKA.init(servKP.getPrivate(), servParamSpec);
servKA.doPhase(servCliPub, true);
byte[] servSecret = servKA.generateSecret();
System.out.println("Server S:" + byteToHex(servSecret));
/////////////////////////////// Client gens secret
KeyAgreement cliKA = KeyAgreement.getInstance("DH");
cliKA.init(cliKP.getPrivate(), cliParamSpec);
cliKA.doPhase(cliServPub, true);
byte[] cliSecret = cliKA.generateSecret();
System.out.println("Client S:" + byteToHex(cliSecret));
////////////////////////////// Check
if (Arrays.equals(cliSecret, servSecret)) System.out.println("MATCH!");
} catch (Exception e) {
e.printStackTrace();
}
}
private static String byteToHex(byte[] array) {
return DatatypeConverter.printHexBinary(array);
}
private static byte[] hexToByte(String string) {
return DatatypeConverter.parseHexBinary(string);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment