Problem importing existing ECC key onto Nitrokey


I have followed the solution from this thread to import an existing ECC key onto my nitrokey: Nitrokey HSM 2: Import existing private and public keys for ECDSA

However, some plugin code that previously worked (on ECC keys created on the nitrokey using scsh) is now throwing an error when I use X509CertificateGenerator - it fails in PKIXCommon.js#372 (OpenSCDP 3.17.459) when i call X509CertificateGenerator’s function addSubjectKeyIdentifierExtension().

The line in PKIXCommon.js that fails is:
algorithm.add(new ASN1(“parameters”, ASN1.OBJECT_IDENTIFIER, publicKey.getComponent(Key.ECC_CURVE_OID)));

I have printed some debug info and can see that when i get the public key from my imported ECC key, it seems valid (ECC_QX component has a sensible value) but the key’s component Key.ECC_CURVE_OID is undefined.

Maybe I have imported my ECC key incorrectly?


I assume you imported the ECC key together with a X.509 certificate ?

How are the domain parameter in the certificate encoded ? Using a named curve or with explicit parameter ?

The code extracts the public key from the certificate object and tries to determine the curve parameter. If publicKey.getComponent(Key.ECC_CURVE_OID) fails, then most likely explicit parameter were encoded in the certificate.

Thanks for your reply. I did indeed import the ECC private key with an X509 certificate by using the instructions from the link above to create a p12 file.

Both the private key and the certificate seem to have been encoded with named curve. when i use “openssl -text …” on both the private key and the certificate, the following appears in the output:
ASN1 OID: prime256v1

When i tried the above on a key encoded with explicit parameters i get very different output (i get values for what i assume are the parameters Prime, A, B, etc.).

But as you say, the X509CertificateGenerator seems to fail because the public key on the hsm has been encoded with explicit parameters (because getComponent(Key.ECC_CURVE_OID) returns undefined).

I don’t understand how the encoding has been changed given that the original private key and certificate are both using named curve.

Is there something i should be setting in the X509CertificateGenerator to warn it about explicit paramters? There weren’t any relevant options when i imported the p12 so i’m not sure what i could have done differently during the import.

The code I have been using sets encodeECDomainParameters (X509CertificateGenerator) to false so i think either i should set this to true, or i fix the encoding back to named curve somehow. But i have ECC keys generated by the HSM that need this value to be false, so do you think this would be a reliable way to set encodeECDomainParameter?

var x = new X509CertificateGenerator(…)
x.encodeECDomainParameter = !publicKey.getComponent(Key.ECC_CURVE_OID)

Or do you think there is a way to make sure the encoding doesn’t change? I would prefer to be able to generate certificates with named curve as that will match a process i am trying to replace in buildroot/arm-trusted-firmware.


1 Like

I have found that the X509CertificateGenerator will not error if i don’t set encodeECDomainParameter at all - however, the imported ECC key is still converted from named curve to explicit parameters at some point in either the import or when accessing the key.

I am using some python scripts on the output from my scsh plugin but they fail because the cryptography library doesn’t support explicit parameters.

Is there a way to prevent the conversion? or convert back to named curve before running X509CertificateGenerator?