Skip to content

Instantly share code, notes, and snippets.

@wuyongzheng
Last active October 29, 2022 14:44
Show Gist options
  • Save wuyongzheng/0e2ed6d8a075153efcd3 to your computer and use it in GitHub Desktop.
Save wuyongzheng/0e2ed6d8a075153efcd3 to your computer and use it in GitHub Desktop.
Elliptic curve Diffie–Hellman using Bouncy Castle v1.50 example code
import java.math.BigInteger;
import java.security.PublicKey;
import java.security.PrivateKey;
import java.security.KeyFactory;
import java.security.Security;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
import java.security.SecureRandom;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.ECGenParameterSpec;
import javax.crypto.KeyAgreement;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.interfaces.ECPublicKey;
import org.bouncycastle.jce.interfaces.ECPrivateKey;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.math.ec.ECPoint;
public class ECDH_BC
{
final protected static char[] hexArray = "0123456789abcdef".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
public static byte [] savePublicKey (PublicKey key) throws Exception
{
//return key.getEncoded();
ECPublicKey eckey = (ECPublicKey)key;
return eckey.getQ().getEncoded(true);
}
public static PublicKey loadPublicKey (byte [] data) throws Exception
{
/*KeyFactory kf = KeyFactory.getInstance("ECDH", "BC");
return kf.generatePublic(new X509EncodedKeySpec(data));*/
ECParameterSpec params = ECNamedCurveTable.getParameterSpec("prime192v1");
ECPublicKeySpec pubKey = new ECPublicKeySpec(
params.getCurve().decodePoint(data), params);
KeyFactory kf = KeyFactory.getInstance("ECDH", "BC");
return kf.generatePublic(pubKey);
}
public static byte [] savePrivateKey (PrivateKey key) throws Exception
{
//return key.getEncoded();
ECPrivateKey eckey = (ECPrivateKey)key;
return eckey.getD().toByteArray();
}
public static PrivateKey loadPrivateKey (byte [] data) throws Exception
{
//KeyFactory kf = KeyFactory.getInstance("ECDH", "BC");
//return kf.generatePrivate(new PKCS8EncodedKeySpec(data));
ECParameterSpec params = ECNamedCurveTable.getParameterSpec("prime192v1");
ECPrivateKeySpec prvkey = new ECPrivateKeySpec(new BigInteger(data), params);
KeyFactory kf = KeyFactory.getInstance("ECDH", "BC");
return kf.generatePrivate(prvkey);
}
public static void doECDH (String name, byte[] dataPrv, byte[] dataPub) throws Exception
{
KeyAgreement ka = KeyAgreement.getInstance("ECDH", "BC");
ka.init(loadPrivateKey(dataPrv));
ka.doPhase(loadPublicKey(dataPub), true);
byte [] secret = ka.generateSecret();
System.out.println(name + bytesToHex(secret));
}
public static void main (String [] args) throws Exception
{
Security.addProvider(new BouncyCastleProvider());
KeyPairGenerator kpgen = KeyPairGenerator.getInstance("ECDH", "BC");
kpgen.initialize(new ECGenParameterSpec("prime192v1"), new SecureRandom());
KeyPair pairA = kpgen.generateKeyPair();
KeyPair pairB = kpgen.generateKeyPair();
System.out.println("Alice: " + pairA.getPrivate());
System.out.println("Alice: " + pairA.getPublic());
System.out.println("Bob: " + pairB.getPrivate());
System.out.println("Bob: " + pairB.getPublic());
byte [] dataPrvA = savePrivateKey(pairA.getPrivate());
byte [] dataPubA = savePublicKey(pairA.getPublic());
byte [] dataPrvB = savePrivateKey(pairB.getPrivate());
byte [] dataPubB = savePublicKey(pairB.getPublic());
System.out.println("Alice Prv: " + bytesToHex(dataPrvA));
System.out.println("Alice Pub: " + bytesToHex(dataPubA));
System.out.println("Bob Prv: " + bytesToHex(dataPrvB));
System.out.println("Bob Pub: " + bytesToHex(dataPubB));
doECDH("Alice's secret: ", dataPrvA, dataPubB);
doECDH("Bob's secret: ", dataPrvB, dataPubA);
}
}
$ javac -cp .:bcprov-jdk15on-150.jar ECDH_BC.java
$ java -cp .:bcprov-jdk15on-150.jar ECDH_BC
Alice: EC Private Key
S: 7b957721204d4290edcb5f1420988ddd9ab9ffc97c8905dd
Alice: EC Public Key
X: 4384a964ca4840b4a085054764fa2f597a16a42ea822896
Y: 62e33641881715e624851242fd7ab360dd8a908dc35d3a7a
Bob: EC Private Key
S: f8ec571d10500474e577633e75342319d779f2ad345ac3f7
Bob: EC Public Key
X: 8dcaf55783a679ae29d0cd93a236187988e3f43636e8ec8f
Y: 7c7613d284c0b054fea567a6790c91a91cde96d1178d9a3d
Alice Prv: 7b957721204d4290edcb5f1420988ddd9ab9ffc97c8905dd
Alice Pub: 0204384a964ca4840b4a085054764fa2f597a16a42ea822896
Bob Prv: 00f8ec571d10500474e577633e75342319d779f2ad345ac3f7
Bob Pub: 038dcaf55783a679ae29d0cd93a236187988e3f43636e8ec8f
Alice's secret: 15e53462327effedb5da725bfe9610a3d106088d73e522e4
Bob's secret: 15e53462327effedb5da725bfe9610a3d106088d73e522e4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment