Prerequisites
Make sure that you have read the last two articles in our series. There are no additional dependencies, but follow along “Nitro HSM Setup” to get a working environment created. You will need your nitrokey’s SO pin in order to perform these operations.
Getting Started
It’s worth noting that the M of N scheme must be asserted when the device is first provisioned. Otherwise, you will want to re-provision it which erases all key material on the device.
First, we will create a DKEK with 4 “password shares” and a threshold requiring 2 of them to be present in order to decrypt the DKEK.
shell
sc-hsm-tool --create-dkek-share dkek-share-1.pbe --pwd-shares-threshold 2 --pwd-shares-total 4
Key Custodian 1 should keep these values secret. Then, they should press enter, and walk away.
Key Custodian 2 should press enter to receive their secret.
It is time for Key Custodian 2 to press enter and walk away.
This process is repeated until each of the 4 key custodians has exclusive access to only their secret.
Finally, the DKEK is enciphered and written to the file system. Each key custodian should keep a copy of the DKEK for redundancy’s sake, but it is only useful for import if M of N custodians are present to provide their secret!
Now we will use this specially crafted DKEK for provisioning our device.
shell
sc-hsm-tool --initialize --so-pin env:SOPIN --pin env:USERPIN --dkek-shares 1
Finally, we import the DKEK. Each custodian will be asked to provide their secret.
shell
sc-hsm-tool --import-dkek-share dkek.pbe --pwd-shares-total 4
Each key custodian receives the same “Prime” value, and a unique Share ID and Share Value. The first Key Custodian is prompted to present BOTH the shared Prime and their custodian secret.
The DKEK is deciphered and the plaintext key is imported onto the NitroKey.
Creating a Key
We can’t very well export a key that doesn’t exist, so let’s create one now in order to demonstrate the key export. Notice that the pin, NOT the SO PIN is needed for this operation.
shell
pkcs11-tool --module /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so -l --pin 648219 --keypairgen --key-type rsa:2048 --id 10
Use the following to enumerate keys on the device:
shell
pkcs15-tool -D
Take note of the “Key ref” value. This will be used as input to the next command.
shell
sc-hsm-tool --wrap-key wrap-key.bin --key-reference 1 --pin 648219
This will generate a file, wrap-key.bin which must be saved somewhere safe.
In order to restore this key material to another NitroKey, it must have been provisioned with the SAME DKEK (which as you remember requires at least 2 of the 4 possible key shares).
Then, it can be imported onto the new device with:
shell
sc-hsm-tool --unwrap-key wrap-key.bin --key-reference 10 --pin 648219
Setting up your replacement NitroKey
Initialize the device:
shell
sc-hsm-tool --initialize --so-pin 25F73632F138383F --pin 648219 --dkek-shares 1 sc-hsm-tool --import-dkek-share dkek.pbe --pwd-shares-total 2
Note that we are only using 2 of the 4 key shares here, to demonstrate that we only need m of n custodians to import a key. I elected to provide share IDs 3 and 4.
Notice that because we’ve initialized the device for the first time...
shell
pkcs15-tool -D
returns no keys present.
Issue:
shell
sc-hsm-tool --unwrap-key wrap-key.bin --key-reference 10 --pin 648219
to import your wrap-key.bin onto the new device.
Once again, issue:
shell
pkcs15-tool -D
We see that the key has been imported back onto the device.
Conclusion
The NitroKey HSM has a mature mechanism for splitting up ultimate responsibility for the security of the key material amongst multiple key custodians. This protects against not only attack from an external party, but from disgruntled employees trying to do damage on their way out the door. This is an extremely impressive feature for a device that comes in at such a low price point. Even some of the bigger players in the space do not provide such an elegant solution.
Discussions and Comments
Click here to view and join in on any discussions and comments on this article.