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();
In the Diffie–Hellman key exchange scheme, each party generates a public/private key pair and distributes the public key. After obtaining an authentic copy of each other's public keys, Alice and Bob can compute a shared secret offline. The shared secret can be used, for instance, as the key for a symmetric cipher.
X25519 is an elliptic curve Diffie-Hellman key exchange using Curve25519. It allows two parties to jointly agree on a shared secret using an insecure channel.
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.
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();
}
}
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
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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With