Created
September 6, 2015 19:58
-
-
Save mhberryman/f22b3668e6b08e1fbfbc to your computer and use it in GitHub Desktop.
A simple script to play with Diffie-Hellman key exchange
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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