Nitrokey Pro 2 - PKCS#11 key generation with Java and OpenSC

Greetings, i met an issue where i can not generate key(–keygen) and key pair (–keypairgen) with OpenSc 0.22, i installed both for x64 and x32, also NitrokeyApp is started and Nitrokey Pro 2 is inserted. The main goal is to be able to sign data with java using private key stored in Nitrokey Pro 2

pkcs11-tool.exe --keygen
Using slot 0 with a present token (0x0)
error: PKCS11 function C_GenerateKey failed: rv = CKR_FUNCTION_NOT_SUPPORTED (0x54)
Aborting.

pkcs11-tool.exe --keypairgen
Using slot 0 with a present token (0x0)
error: PKCS11 function C_GenerateKeyPair failed: rv = CKR_FUNCTION_NOT_SUPPORTED (0x54)
Aborting.

facing error “CKR_FUNCTION_NOT_SUPPORTED (0x54)” via cmd and also in java. My thoughts is about initialization, could you help me please

Hi @Vlasonag !

  1. Nitrokey App is not needed for the smart card interaction, so it can be safely closed.
  2. Key generation through pkcs11-tool should just work. Make sure Nitrokey Pro is the selected smart card (use reader selection - sometimes some other hardware is listed first). You can check that with:
    # list all slots
    $ pkcs11-tool.exe -L
    
    Then the slot can be selected by --slot param.
  3. Please take a look at below links, which hopefully will have some suggestions:

Thanks for your answer
I have only one smart card inserted, still reproduces:

pkcs11-tool.exe -L
Available slots:
Slot 0 (0x0): Nitrokey Nitrokey Pro 0
  token label        : OpenPGP card (User PIN)
  token manufacturer : ZeitControl
  token model        : PKCS#15 emulated
  token flags        : login required, rng, token initialized, PIN initialized
  hardware version   : 3.3
  firmware version   : 3.3
  serial num         : 00050000993f
  pin min/max        : 6/64
Slot 1 (0x1): Nitrokey Nitrokey Pro 0
  token label        : OpenPGP card (User PIN (sig))
  token manufacturer : ZeitControl
  token model        : PKCS#15 emulated
  token flags        : login required, rng, token initialized, PIN initialized
  hardware version   : 3.3
  firmware version   : 3.3
  serial num         : 00050000993f
  pin min/max        : 6/64

pkcs11-tool.exe -k --slot 0
error: PKCS11 function C_GenerateKeyPair failed: rv = CKR_FUNCTION_NOT_SUPPORTED (0x54)
Aborting.

Hey @Vlasonag

pkcs11-tool uses a keysize of 1024 by default, and the Pro does only support 2048 for generation, as you can see in pkcs11-tool -M: (edit: the Nitrokey Pro actually does, but recent OpenSC versions limit it to keysizes)

...
RSA-PKCS-KEY-PAIR-GEN, keySize={2048,2048}, generate_key_pair
...

so you’ll have to pass the proper keysize as --key-type RSA:2048, for me the key generation works with the following command line:

$ pkcs11-tool --login-type so --pin 12345678 --so-pin 12345678 -k --key-type RSA:2048 --slot 0

Key pair generated:
Private Key Object; RSA 
  label:      Private Key
  ID:         e813d1180bb86188682b7969bb32c7b5d12eb4fa
  Usage:      decrypt, sign
  Access:     none
Public Key Object; RSA 16384 bits
  label:      Private Key
  ID:         e813d1180bb86188682b7969bb32c7b5d12eb4fa
  Usage:      encrypt, verify
  Access:     none

depending on how you providing your pin the command may differ, the essential part is: -k --key-type RSA:2048

disclaimer: never use pins in commandlines :wink:

edit: you can also see the PKCS#11 commands directly used for generation (if you need them to do this in code) by just setting OPENSC_DEBUG=9 as environment variable, then you should see many debug output, search it for C_GenerateKeyPair and you’ll see the PKCS#11 arguments passed to the RSA-PKCS-KEY-PAIR-GEN mechanism.

cheers

1 Like

Not exactly. This depends on the OpenSC version, as it hardcodes the supported algorithms inside the implementation. Nitrokey Pro 2 (OpenPGP v3.3+) allows to generate both 2k and 4k RSA (and its possible to do so with GnuPG). OpenSC is limiting this to 4k only since v0.21 as far as I see.
You must have used older version of the library during the test. Good catch with the default algo though.

# OpenSC version 0.21
$ pkcs11-tool -M | grep RSA-PKCS-KEY-PAIR-GEN
  RSA-PKCS-KEY-PAIR-GEN, keySize={4096,4096}, generate_key_pair  

$ pkcs11-tool --login-type so --pin 12345678 --so-pin 12345678 -k --key-type RSA:4096 --slot 0
Key pair generated:
Private Key Object; RSA 
  label:      Private Key
  ID:         05e99683fa82b165332c4a81b2ac03413412a39a
  Usage:      decrypt, sign
  Access:     none
Public Key Object; RSA 32768 bits
  label:      Private Key
  ID:         05e99683fa82b165332c4a81b2ac03413412a39a
  Usage:      encrypt, verify
  Access:     none

Fair warning @Vlasonag : it takes about 2 minutes to generate the 4k RSA key (96s in my case).

oops, clearly correct, added a note the post

Thank you helping me generating the key pair, now i have to ask you why is “Access: none”, does it mean that i am not able to get privakte key and sign data? In Java i am trying to find PKCS11Objects(PrivateKey) even i generated key pair the array of objects is empty. Is it about “Access: none”?

If I understand correctly, what you are searching for is the Usage attribute, which defines what possible operations are available. Access attribute here should describe the raw byte access to the secret material. I am not sure about this, but modifying this attribute might not be available to the OpenPGP card in Nitrokey Pro and is rather hard-coded in the implementation with a default behavior, as opposed to Nitrokey HSM.
The example how does it look like for the latter is on the OpenSC Wiki:

Additionally, OpenPGP cards do not store public keys, only private ones.

As for why the PKCS11 object list does not contain the private key - can you check that first with the OpenSC tooling? E.g.

$ pkcs11-tool -l --pin 123456 --list-objects

Using slot 0 with a present token (0x0)
Private Key Object; RSA 
  label:      Encryption key
  ID:         02
  Usage:      decrypt, unwrap
  Access:     sensitive, always sensitive, never extractable, local
Public Key Object; RSA 4096 bits
  label:      Encryption key
  ID:         02
  Usage:      encrypt, wrap
  Access:     none
Private Key Object; RSA 
  label:      Authentication key
  ID:         03
  Usage:      decrypt, sign, non-repudiation, unwrap
  Access:     sensitive, always sensitive, never extractable, local
Public Key Object; RSA 4096 bits
  label:      Authentication key
  ID:         03
  Usage:      encrypt, verify, wrap
  Access:     none

Here while the public key is listed, it is most certainly not available to be read from the smart card, and the public part of the keypair has to be carried over using other means (and none is just a placeholder).

Hello, that is what i got after generating and listing objects:

pkcs11-tool.exe -l --pin 123456 --list-objects
Using slot 0 with a present token (0x0)
Profile object 32506608
  profile_id:          '4'

Looks like keys were not generated

Indeed. Please try the generation again.
Alternatively you can set the OPENSC_DEBUG=9 environment variable, which will result in a detailed operation log, hopefully revealing the cause of the issue.