'How to generate curve25519 key pair for diffie hellman algorithm?
I want to implement ECDHE algorithm in my project ,for that I want to use Curve25519.But stuck how to generate key-pair for Curve25519.With other curve I am able to generate key-pair,but for curve25519 getting algorithm not found
I tried with below code:
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
kpg.initialize(256);
KeyPair private_Key1 = kpg.generateKeyPair();
PublicKey ourPk1 = private_Key1.getPublic();
Solution 1:[1]
You could use BouncyCastle
as cryptographic provider which has support for this curve :
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
public class Test {
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
X9ECParameters curveParams = CustomNamedCurves.getByName("Curve25519");
ECParameterSpec ecSpec = new ECParameterSpec(curveParams.getCurve(), curveParams.getG(), curveParams.getN(), curveParams.getH(), curveParams.getSeed());
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
kpg.initialize(ecSpec);
KeyPair keyPair = kpg.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
}
}
Extracting raw public key
To extract raw x
and y
of ECPoint
(public key) you can use this code:
byte[] encoded = publicKey.getEncoded();
ASN1Sequence asn1Primitive = ASN1Sequence.getInstance(encoded);
ASN1Encodable algorithmIdentifier = asn1Primitive.getObjectAt(0);
DERBitString ecPointBitString = (DERBitString) asn1Primitive.getObjectAt(1);
//use curve parameters from previous code snippet
ECPoint ecPoint = curveParams.getCurve().decodePoint(ecPointBitString.getOctets());
byte[] x = ecPoint.getAffineXCoord().getEncoded();
byte[] y = ecPoint.getAffineYCoord().getEncoded();
This is basically parsing the encoded SubjectPublicKeyInfo
described in RFC5480
Extracting raw private key
BCECPrivateKey privateKey1 = (BCECPrivateKey) privateKey;
byte[] bigIntPk = privateKey1.getS().toByteArray();
or by parsing DER objects :
ASN1Sequence instance = ASN1Sequence.getInstance(privateKey.getEncoded());
DEROctetString pkOctetString = (DEROctetString) instance.getObjectAt(2);
ASN1Sequence ecPkSequence = DERSequence.getInstance(pkOctetString.getOctets());
DEROctetString pkOctets = (DEROctetString) ecPkSequence.getObjectAt(1);
byte[] bigIntPk = new BigInteger(1, pkOctets.getOctets()).toByteArray();
Solution 2:[2]
Curve25519 seems supported from Java 11 onwards (note that the standard Java follows the OpenJDK Java nowadays).
The linked to JEP (Java Enhancement Proposal) also contains sample code, included here verbatim:
KeyPairGenerator kpg = KeyPairGenerator.getInstance("XDH");
NamedParameterSpec paramSpec = new NamedParameterSpec("X25519");
kpg.initialize(paramSpec); // equivalent to kpg.initialize(255)
// alternatively: kpg = KeyPairGenerator.getInstance("X25519")
KeyPair kp = kpg.generateKeyPair();
KeyFactory kf = KeyFactory.getInstance("XDH");
BigInteger u = ...
XECPublicKeySpec pubSpec = new XECPublicKeySpec(paramSpec, u);
PublicKey pubKey = kf.generatePublic(pubSpec);
KeyAgreement ka = KeyAgreement.getInstance("XDH");
ka.init(kp.getPrivate());
ka.doPhase(pubKey, true);
byte[] secret = ka.generateSecret();
Note that the public key generated by the key factory is the one from the other party. Usually you would decode that value from bytes though.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Maarten Bodewes |