bc-java
bc-java copied to clipboard
Failed to create SubjectPublicKeyInfo from EC public key
Hello, I have very specific constrint to generate a x509 certificate with public key 64 bytes (X coordinate + Y coordinate).
PFB code,
Security.addProvider(new BouncyCastleProvider()); ECNamedCurveParameterSpec parameterSpec = ECNamedCurveTable.getParameterSpec(EllipticCurveName.prime256v1.name()); KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDH", BouncyCastleProvider.PROVIDER_NAME);
keyPairGenerator.initialize(parameterSpec, new SecureRandom());
KeyPair keyPair = keyPairGenerator.generateKeyPair();
ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();
byte[] publicKeyInBytes = getECPublicKeyInBytes(publicKey);
SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(publicKeyInBytes);
public static byte[] getECPublicKeyInBytes(PublicKey publicKey, int keySize) { LOGGER.debug("Key size is {}", keySize); ECPublicKey ecPublicKey = (ECPublicKey) publicKey; byte[] x = bi2ba(ecPublicKey.getW().getAffineX(), keySize / 8); byte[] y = bi2ba(ecPublicKey.getW().getAffineY(), keySize / 8); return Bytes.concat(x, y); }
/**
* Convert big integer structure to byte array
*
* @param bi
* @param expectedLen
* Expected array length in bytes (32 or 48).
* @return
*/
private static byte[] bi2ba(BigInteger bi, int expectedLen) {
byte[] ba = bi.toByteArray();
if (expectedLen > ba.length) {
// Fill the begin of the array with zeros up to the expected length
ba = Bytes.concat(new byte[expectedLen - ba.length], ba);
}
if (expectedLen < ba.length) {
// Get only the latest bytes of the array
ba = Arrays.copyOfRange(ba, ba.length - expectedLen, ba.length);
}
return ba;
}
The issue i am getting is,
Exception in thread "main" java.lang.IllegalArgumentException: failed to construct sequence from byte[]: corrupted stream - out of bounds length found: 123 >= 64 at org.bouncycastle.asn1.ASN1Sequence.getInstance(ASN1Sequence.java:101) at org.bouncycastle.asn1.x509.SubjectPublicKeyInfo.getInstance(SubjectPublicKeyInfo.java:44) at com.nagra.iot.ilps.Test.main(Test.java:40)
Can some one help how to create SubjectPublicKeyInfo object with the public key having X and Y.
Compare what you are generating with publicKey.getEncoded() and you will see what is missing.
Is it necessary only to send 'publicKey.getEncoded()' byte array (length is 91 bytes) to subjectPublicKeyInfo ?
I want to send the publickey retrieved as X+Y coordinates byte array. (the length is 64 bytes)
Yes. The SubjectPublicKeyInfo structure contains additional data as well as the point values.