Using command line tool (like pkcs11-tool) to write key and certificate in Nitrokey HSM

I use Smart Card Shell 3 to populate the Nitrokey HSM with certificates and keys.
Is there any way to do the same thing using only command line tools (not gui) like with pkcs11-tool?


Yes, look here for details.

However, not all mechanisms are available at the PKCS#11 interface. Our recommendation is to use the Smart Card Shell (or a set of scripts) to manage keys and use PKCS#11 middleware to use those keys.

I have .pem (or even .der) files containing private key and certificate.
Is it possible to import the private key from a file as well?


The easiest way is to import a key and certificate from a PKCS#12 file.

Vesselin Kolev wrote a nice tutorial.

But you can also use an OpenSCDP script to do that. The sc-hsm-workspace in the Starterkit has a script examples/importRSAKeyandCert.js that does that for you.

this tutorial does not describe how to get to populate Nitrokey using only the command line. Suppose I have a system without a GUI, such as Ubuntu server, I could not use Smart Card Shell 3.

I will try this.


That is because importing key material defeats the purpose of using an HSM: With a HSM you want to have control of key material over it’s entire lifetime. Compare it with a hot-cell in which you handle radioactive material: At no time you want the material to be exposed, same with keys.

I understand, that for testing purposes you want to work with known keys and the Smart Card Shell provides the tools for that.

If you want to do key management seriously (like in a CP/CPS), then you need some organizational structure, like key custodians, shared responsibility and dual control. The HSM allows you to support such structures with key domains, n-of-m in control and authentication.

this explanation puts me in doubt that I have not chosen the right tool.
Let me explain my use case:
I have a microcontroller (specifically NXP’s RT1051 and RT1175).
It is capable of verifying a firmware signature and running encrypted firmware (decrypting it on the fly).
For the moment, let us focus only on the signature. I write the firmware, compile it, then have to sign it. In the microcontroller though, there’s a need to write something into it that allows it to validate the signed firmware. This information has to be written in the production facility, and it is OTP.
Without going into details, though, that’s why I need to have all the keys and certificates available outside of Nitrokey.
And we were only thinking of Nitrokey to minimize the spread of keys.

Then there’s the encryption aspect. The microcontroller supports AES128, so symmetric key. I haven’t found a way for Nitrokey to store the key with which I can then encrypt my executable.
So the encryption step is still done by hand with key stored on a filesystem (not necessarily the same one where the compilation takes place)

Of course I have many projects using this microcontroller, and each one has its own keys and certificates.

That said, is there a more suitable tool than the Nitrokey HSM?


It is the right tool for the job, I just doubt, that you need to have the private key externally.

The scheme you describe relies on two mechanisms, a private key signing the firmware and a trusted signature verification in the firmware. Trusted, because you can only write the public key (or certificate) once during production. So as soon as you have done this, the security relies on control over the private key. If you have generated that key in a HSM, you have control over physical spread. If you generate that key outside and later import it, you still have a copy outside the HSM and you can never be sure that no further copies exists (e.g. you take a backup and key material spreads on the backup media).

Of course you will ask: What of the HSM goes defect ? How do I recover ?

That is where the backup mechanism kicks in. It allows you to securely extract the key into an external backup and restore key material on a new device. But that of course requires some organizational security, namely to make the new device fit to participate in key exchange with the first HSM. We call that a key domain, as it describes the group of HSMs in which key material can float (for backup, scaling or fault tolerance). Controlling the key domain is what the organizational overhead needs to ensure.

Typically what you would need to do:

  1. Identify trustworthy people (key custodians)
  2. Have each key custodian generate a DKEK key share using the sc-hsm-tool
  3. Have each key custodian import their share into the HSM

At this point the HSM is part of a key domain controlled by the key custodians. Now you can continue:

  1. Generate key material (Signing key, encryption key)
  2. Export key material under the combined DKEK and place in backup media
  3. Use key materials as required

In case of a loss:

  1. Get a new HSM
  2. Have each key custodian import their share into the HSM
  3. Import the backup from step 5 into the HSM

So once you have all the key material in the HSM, you need to integrate with your firmware build system. You need to apply encryption with the AES key on the device and sign using the private signing key.

If you already have a tool for that, then it might support PKCS#11 as interface to the HSM. If you want to write your own, you could use things like the Python PKCS#11 interface, our own OCF/JCE-Provider or an OpenSCDP script.

Personally, I would just write a script for the Smart Card Shell that prompts to select a file, encrypt and sign it.

But you will of course need to have full details on the cryptography applied here. What format does the encrypted file have, how is the AES key transmitted and such details.

1 Like

we rely on tools that NXP itself provides. Under the hood these use, among other things, openssl1.1 with the pkcs11 engine.
These tools take care of decorating the executable with appropriate headers and footers. The layout of these memory areas is poorly documented, so we are forced to use these tools. And these tools require us to have the encryption key and signing private key (in some form) available. It would be worth studying whether this is strictly necessary, and whether there is a way to extract it from the token.

Are those tool publicly available ? Did you already try to integrate those tools with PKCS#11 ?

Seems like we need to do the integration, which is typically difficult for closed source.

A step by step approach would be to setup a token with the required keys and configure OpenSC with the pkcs11spy. That way you can see what operations the NXP tool is performing and we can step by step figure out what they expect.

It is possible to use NXP tools with Nitrokey HSM, you can use PKCS#11 interfaces for that. I’ve seen this done with CST tools from NXP. I have also made HAB signing work with Nitrokey HSM without using CST.