How to make Bouncy Castle ECPublicKey

I know the name of the curve ( secp256k1 ) and the X and Y coordinates of the EU public key.

How do I make org.bouncycastle.jce.interfaces.ECPublicKey of them?

I was reading https://stackoverflow.com/a/166268/ but in the code instead of org.bouncycastle... used java.security... and ECPublicKey is the interface in org.bouncycastle... and not an instance of the class.

+5
source share
2 answers

Creating ECPublicKey Using Bouncy Castle

This generates the EU public key used in the JCE / JCA. The Bouncy Castle provider can directly use these software keys. Otherwise, Bouncy is simply used to generate the parameters needed to generate the public key.

 package nl.owlstead.stackoverflow; import static java.nio.charset.StandardCharsets.US_ASCII; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPairGenerator; import java.security.Security; import java.security.interfaces.ECPublicKey; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.ECPublicKeySpec; import javax.crypto.Cipher; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.util.encoders.Hex; public class ECPublicKeyFactory { public static void main(String[] args) throws Exception { String name = "secp256r1"; Security.addProvider(new BouncyCastleProvider()); // === NOT PART OF THE CODE, JUST GETTING TEST VECTOR === KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "BC"); ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec(name); kpg.initialize(ecGenParameterSpec); ECPublicKey key = (ECPublicKey) kpg.generateKeyPair().getPublic(); byte[] x = key.getW().getAffineX().toByteArray(); byte[] y = key.getW().getAffineY().toByteArray(); // === here the magic happens === KeyFactory eckf = KeyFactory.getInstance("EC"); ECPoint point = new ECPoint(new BigInteger(1, x), new BigInteger(1, y)); ECNamedCurveParameterSpec parameterSpec = ECNamedCurveTable.getParameterSpec(name); ECParameterSpec spec = new ECNamedCurveSpec(name, parameterSpec.getCurve(), parameterSpec.getG(), parameterSpec.getN(), parameterSpec.getH(), parameterSpec.getSeed()); ECPublicKey ecPublicKey = (ECPublicKey) eckf.generatePublic(new ECPublicKeySpec(point, spec)); System.out.println(ecPublicKey.getClass().getName()); // === test 123 === Cipher ecies = Cipher.getInstance("ECIESwithAES", "BC"); ecies.init(Cipher.ENCRYPT_MODE, ecPublicKey); byte[] ct = ecies.doFinal("owlstead".getBytes(US_ASCII)); System.out.println(Hex.toHexString(ct)); } } 

Creating Bouncy Castle ECPublicKeyParameters

Initially, I thought that a special Bouncy Castle key was required, so the following code generates the EC public key used in the Bouncy Castle lightweight API.

 package nl.owlstead.stackoverflow; import java.math.BigInteger; import java.security.KeyPairGenerator; import java.security.Security; import java.security.interfaces.ECPublicKey; import java.security.spec.ECGenParameterSpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.params.ECNamedDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.encoders.Hex; public class BC_EC_KeyCreator { public static void main(String[] args) throws Exception { String name = "secp256r1"; // === NOT PART OF THE CODE, JUST GETTING TEST VECTOR === Security.addProvider(new BouncyCastleProvider()); KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "BC"); kpg.initialize(new ECGenParameterSpec(name)); ECPublicKey key = (ECPublicKey) kpg.generateKeyPair().getPublic(); byte[] x = key.getW().getAffineX().toByteArray(); byte[] y = key.getW().getAffineY().toByteArray(); // assumes that x and y are (unsigned) big endian encoded BigInteger xbi = new BigInteger(1, x); BigInteger ybi = new BigInteger(1, y); X9ECParameters x9 = ECNamedCurveTable.getByName(name); ASN1ObjectIdentifier oid = ECNamedCurveTable.getOID(name); ECCurve curve = x9.getCurve(); ECPoint point = curve.createPoint(xbi, ybi); ECNamedDomainParameters dParams = new ECNamedDomainParameters(oid, x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); ECPublicKeyParameters pubKey = new ECPublicKeyParameters(point, dParams); System.out.println(pubKey); // some additional encoding tricks byte[] compressed = point.getEncoded(true); System.out.println(Hex.toHexString(compressed)); byte[] uncompressed = point.getEncoded(false); System.out.println(Hex.toHexString(uncompressed)); } } 

This was mostly complicated because I did not want to include any JCE code, and X9ECParameters not a subclass of ECDomainParameters . Therefore, I used the conversion to ECNamedDomainParameters , copied from another place in the Bouncy Castle code base.

+7
source

In the following code, encoded contains 0x04 , followed by 32 bytes X, then 32 bytes Y.

Alternatively, it may contain 0x02 or 0x03 (depending on the sign of Y), followed by 32 bytes of X.

 public static ECPublicKey decodeKey(byte[] encoded) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException{ ECNamedCurveParameterSpec params = ECNamedCurveTable.getParameterSpec("secp256k1"); KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC"); ECCurve curve = params.getCurve(); java.security.spec.EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, params.getSeed()); java.security.spec.ECPoint point = ECPointUtil.decodePoint(ellipticCurve, encoded); java.security.spec.ECParameterSpec params2 =EC5Util.convertSpec(ellipticCurve, params); java.security.spec.ECPublicKeySpec keySpec = new java.security.spec.ECPublicKeySpec(point,params2); return (ECPublicKey) fact.generatePublic(keySpec); } 
+2
source

Source: https://habr.com/ru/post/1234039/


All Articles