I am working on a personal project in Java which involves sending sensitive data over an insecure channel. I need to know how to implement Diffie Hellman Key Exchange (DHKE) in
Following code uses Elliptic Curve Diffie-Hellman to generate and share 128bit key and AES for encryption.
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.*;
public class AESSecurityCap {
private PublicKey publickey;
KeyAgreement keyAgreement;
byte[] sharedsecret;
String ALGO = "AES";
AESSecurityCap() {
makeKeyExchangeParams();
}
private void makeKeyExchangeParams() {
KeyPairGenerator kpg = null;
try {
kpg = KeyPairGenerator.getInstance("EC");
kpg.initialize(128);
KeyPair kp = kpg.generateKeyPair();
publickey = kp.getPublic();
keyAgreement = KeyAgreement.getInstance("ECDH");
keyAgreement.init(kp.getPrivate());
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
}
}
public void setReceiverPublicKey(PublicKey publickey) {
try {
keyAgreement.doPhase(publickey, true);
sharedsecret = keyAgreement.generateSecret();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
}
public String encrypt(String msg) {
try {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(msg.getBytes());
return new BASE64Encoder().encode(encVal);
} catch (BadPaddingException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
return msg;
}
public String decrypt(String encryptedData) {
try {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
byte[] decValue = c.doFinal(decordedValue);
return new String(decValue);
} catch (BadPaddingException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
}
return encryptedData;
}
public PublicKey getPublickey() {
return publickey;
}
protected Key generateKey() {
return new SecretKeySpec(sharedsecret, ALGO);
}
}
Extend your own class to add AES encrypting feature
public class Node extends AESSecurityCap {
//your class
}
Finally, way to use the encryption
public class Main {
public static void main(String[] args) throws IOException {
Node server = new Node();
Node client = new Node();
server.setReceiverPublicKey(client.getPublickey());
client.setReceiverPublicKey(server.getPublickey());
String data = "hello";
String enc = server.encrypt(data);
System.out.println("hello is coverted to "+enc);
System.out.println(enc+" is converted to "+client.decrypt(enc));
}
}
output:
hello is coverted to OugbNvUuylvAr9mKv//nLA==
OugbNvUuylvAr9mKv//nLA== is converted to hello
Process finished with exit code 0