bc-java icon indicating copy to clipboard operation
bc-java copied to clipboard

Failed to create SubjectPublicKeyInfo from EC public key

Open phani50 opened this issue 3 years ago • 2 comments

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.

phani50 avatar Sep 29 '22 21:09 phani50

Compare what you are generating with publicKey.getEncoded() and you will see what is missing.

dghgit avatar Sep 30 '22 03:09 dghgit

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)

phani50 avatar Sep 30 '22 08:09 phani50

Yes. The SubjectPublicKeyInfo structure contains additional data as well as the point values.

dghgit avatar Dec 28 '22 09:12 dghgit