Does Nitrokey support brainpoolP256t1? (I'm getting an invalid key)


Summary of the problem: when I generate a t1 ECC key, the nitrokey seems to generate an invalid key with EC parameters that match t1 but it has a curve oid of r1.

I am developing for a secure platform that requires the use of a brainpoolP256t1 EC key.
I am using Smart Card Shell (Scripting Engine 3.17.459).
I have modified Keymanager.js:

  1. to add “brainpoolP256t1” to Keymanager.CURVES list (so it appears as an option when generating an ECC key).
  2. to output some info when it generates a new ECC key; in Keymanager.js:generateECCKey(…)

I log in to my Nitrokey and choose “Generate ECC Key”. I select curve “brainpoolP256t1” and choose a label “ECC_T”.

Note that the OID for brainpoolP256t1 is 2B 24 03 03 02 08 01 01 08.
brainpoolP256r1 is 2B 24 03 03 02 08 01 01 07

Inside the function Keymanager.generateECCKey(…) the original code creates a key description correctly (with the t1 curve) and then calls this.ks.generateKeyPair(…) and this.ks.storeEndEntityCertificate(…) to generate the key.

The tree view on the left will then update after the call to this.createOutline(…)

The code i added then outputs the original key requested, and then fetches the actual key via the OutlineNode tree. Here’s what I get:

Generating key can take up to 60 seconds, please wait...
Key generated
Original request for new ECC key:
EC Parameter:
  prime A9 FB 57 DB A1 EE A9 BC 3E 66 0A 90 9D 83 8D 72 6E 3B F6 23 D5 26 20 28 20 13 48 1D 1F 6E 53 77
  curve a A9 FB 57 DB A1 EE A9 BC 3E 66 0A 90 9D 83 8D 72 6E 3B F6 23 D5 26 20 28 20 13 48 1D 1F 6E 53 74
  curve b 66 2C 61 C4 30 D8 4E A4 FE 66 A7 73 3D 0B 76 B7 BF 93 EB C4 AF 2F 49 25 6A E5 81 01 FE E9 2B 04
  generator x A3 E8 EB 3C C1 CF E7 B7 73 22 13 B2 3A 65 61 49 AF A1 42 C4 7A AF BC 2B 79 A1 91 56 2E 13 05 F4
  generator y 2D 99 6C 82 34 39 C5 6D 7F 7B 22 E1 46 44 41 7E 69 BC B6 DE 39 D0 27 00 1D AB E8 F3 5B 25 C9 BE
  order A9 FB 57 DB A1 EE A9 BC 3E 66 0A 90 9D 83 8D 71 8C 39 7A A3 B5 61 A6 F7 90 1E 0E 82 97 48 56 A7
  cofactor 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01

Curve = 2B 24 03 03 02 08 01 01 08

ECC key when accessed via node view:
New ECC node = ECC_T
New ECC key curve = 2B 24 03 03 02 08 01 01 07

As you can see, the original request is correct - the EC parameters match that expected of a t1 curve and the OID is that of brainpoolP256t1.

However, the last two lines reveal a curve OID of brainpoolP256r1.

Is this a known issue? is there a fix or workaround?


Do you use a Nitrokey HSM 2?

That is an issue in the Smart Card Shell. There is a mapping in GPKey that tries to determine the curve OID from the prime parameter. For brainpoolP256r1 and brainpoolP256t1 that parameter is identical, so the code picks the wrong OID.

As long as you stick with the domain parameter, things should work as expected. You can try the examples/sign.js script to check if the signature works (Use the latest from the sc-hsm-sdk-scripts repo, as I had to fix the domain parameter processing for key attestation).


Thank you for letting me know it’s an issue with Smart Card Shell.

Could you explain what you mean by “As long as you stick with the domain parameter, things should work as expected”? I’m not sure how it will help with my issue:

  1. I create an ECC brainpoolP256t1 key via the keymanager context menu.
  2. I create a certificate in my plugin using X509CertificateGenerator and export it to a file.
  3. Later in our workflow in separate tools i use openssl to process the certificate

The openssl command line tool then throws an error “point is not on curve” - presumably due to the mismatch between the curve OID (which matches brainpoolP256r1) and the public key coordinates (which are on the curve brainpoolP256t1).

My current workaround is to detect the curve in my certificate generator based on the curve parameters - if it finds a mismatch with what the OID says it is, i then use Key.setComponent(…) to set the OID to match the curve parameters. Does that sound a reasonable workaround or does it sound problematic for any reason?

So in summary, i would really appreciate the following:

  1. Clarification about “As long as you stick with the domain parameter, things should work as expected”
  2. Does my workaround sound reasonable? It seems to work so far.

Many thanks,

The SmartCard-HSM itself does not use the OID at all. It’s the OpenSCDP scripting environment or the OpenSC middleware that tries to figure out the OID for given curve parameter in the public key. Both only look at the prime, so brainpoolP256r1 and brainpoolP256t1 look alike.

I guess in your certificate you are using named curves, so you need the correct OID ?

Yes, we are using named curve.

Does my solution above sound reasonable or are there any hidden gotchas when setting the curve OID component? (Presumably there is no danger of it modifying the coordinates of the public key?)

And could you clarify the recommendation to stick with the domain parameter?


Yes, that should work as a temporary fix. Give me some time to resolve the problem in OpenSC and SCSH3.

With “sticj with the domain parameter” I mean to use the decoded public key directly without doing OID based transforms. That will obviously not work with certificates that use named curves.

1 Like


Thank you for your help. Much appreciated