Load ECDSA private key with version 1.59 and beyond

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Load ECDSA private key with version 1.59 and beyond

3ric_T

Hi,

 

When trying to load an ECDSA private key :

 

String privateKey = "MIIBGwIBADCB7AYHKoZIzj0CATCB4AIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wRAQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBBCcwJQIBAQQgQ5Yba7LcVummrWknvTs+3RRxl4Gz/lUCrIoqlGXwy+gB";

KeyFactory factory = KeyFactory.getInstance("ECDSA", "BC");

ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1");

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec( Base64.decode(privateKey) );

factory.generatePrivate(keySpec);

 

I’m facing an error with the versions from 1.59 to latest (1.64):

java.security.spec.InvalidKeySpecException: encoded key spec not recognized: failed to construct sequence from byte[]: Extra data detected in stream

                at org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePrivate(Unknown Source)

                at org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi.engineGeneratePrivate(Unknown Source)

                at java.security.KeyFactory.generatePrivate(KeyFactory.java:366)

 

This did not occur with version 1.53

I can make it work with:

        KeyFactory factory = KeyFactory.getInstance("ECDSA", "BC");

        ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1");

        ECPrivateKeySpec ecPrivateKeySpec = new ECPrivateKeySpec(new BigInteger(1, Base64.decode(privateKey)), spec);

        factory.generatePrivate(ecPrivateKeySpec);

 

More surprisingly, the name of the curve is not important, I just have to precise any well-known name, such as « prime256v1 » or « secp192r1 »…

Could explain it and help me to get rid of using this name ?
Thanks in advance for reading and answering me

Éric

 

Reply | Threaded
Open this post in threaded view
|

Re: Load ECDSA private key with version 1.59 and beyond

David Hook-3

There's an extra byte on the end of the encoding. You'll see it if you use:

String privateKey = "MIIBGwIBADCB7AYHKoZIzj0CATCB4AIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wRAQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBBCcwJQIBAQQgQ5Yba7LcVummrWknvTs+3RRxl4Gz/lUCrIoqlGXwy+gB";
System.err.println(Hex.toHexString(Base64.decode(privateKey)));
ASN1InputStream aIn = new ASN1InputStream(Base64.decode(privateKey));
Object o;
while ((o = aIn.readObject()) != null)
{
    System.err.println(Hex.toHexString(((ASN1Primitive)o).getEncoded()));
}

1.64 won't tolerate the extra data, it does this as since 1.59 came out there have been increasing concerns that improperly constructed ASN.1 data could be used to hide changes else where in a payload, so the parser now checks.

Regards,

David
On 23/6/20 1:08 am, TOURNIER, Eric wrote:

Hi,

 

When trying to load an ECDSA private key :

 

String privateKey = "MIIBGwIBADCB7AYHKoZIzj0CATCB4AIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wRAQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBBCcwJQIBAQQgQ5Yba7LcVummrWknvTs+3RRxl4Gz/lUCrIoqlGXwy+gB";

KeyFactory factory = KeyFactory.getInstance("ECDSA", "BC");

ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1");

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec( Base64.decode(privateKey) );

factory.generatePrivate(keySpec);

 

I’m facing an error with the versions from 1.59 to latest (1.64):

java.security.spec.InvalidKeySpecException: encoded key spec not recognized: failed to construct sequence from byte[]: Extra data detected in stream

                at org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePrivate(Unknown Source)

                at org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi.engineGeneratePrivate(Unknown Source)

                at java.security.KeyFactory.generatePrivate(KeyFactory.java:366)

 

This did not occur with version 1.53

I can make it work with:

        KeyFactory factory = KeyFactory.getInstance("ECDSA", "BC");

        ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1");

        ECPrivateKeySpec ecPrivateKeySpec = new ECPrivateKeySpec(new BigInteger(1, Base64.decode(privateKey)), spec);

        factory.generatePrivate(ecPrivateKeySpec);

 

More surprisingly, the name of the curve is not important, I just have to precise any well-known name, such as « prime256v1 » or « secp192r1 »…

Could explain it and help me to get rid of using this name ?
Thanks in advance for reading and answering me

Éric