“What was previously only provided by expensive and proprietary hardware security modules (HSM) is now available as open hardware at an unbeatably low price from Germany. Nitrokey HSM reliably protects your cryptographic keys with encrypted backups, two-man rule as access protection and many other security features. With a USB interface, Nitrokey HSM is the ideal solution for certificate infrastructures of any type and size."

factory pin: 648219
factory so-pin: 3537363231383830

goals:

  • configure
  • manage ssh
  • backup and restore
  • pki using openssl’s pkcs11 feature

packages required (arch linux)

* ccid
* opensc
* pcsc-tools
* libp11

configure

## enable and start pcscd
> systemctl enable pcscd
> systemctl start pcscd

## run scan and then plug in device
> pcsc_scan

## verify known readers
> opensc-tool --list-readers

## check version
> pkcs11-tool --list-slots

## initialyse key or better known as "be carefull otherwise totally fuck up"
## important: without DKEK share no backups are possible
> sc-hsm-tool \
  --initialize \
  --so-pin 3537363231383830 \
  --pin 648219 \
  --dkek-shares 1

## change pin
> pkcs11-tool \
  --login \
  --pin 648219 \
  --change-pin \
  --new-pin 123456

## change so-pin
> pkcs11-tool \
  --module opensc-pkcs11.so \
  --login \
  --login-type so \
  --so-pin 3537363231383830 \
  --change-pin \
  --new-pin 0123456789012345

## debug with
> OPENSC_DEBUG=9 <command>

manage ssh

## RSA performance:
## RSA-2048: 250 ms, RSA-3074: 1900 ms, RSA-4096: 4100 ms
## create RSA 4096 ssh key named "RSA-Server-4711" with id 8
> pkcs11-tool \
  --module opensc-pkcs11.so \
  --login \
  --pin 123456 \
  --keypairgen \
  --key-type rsa:4096 \
  --id 08 \
  --label "RSA-Server-4711"

## EC performance:
## ECDH-256: 90ms, ECDH-512: 290 ms
## ECDSA-256: 80 ms, ECDSA-512: 190 ms
## create ECDH-521 ssh key named "ECDH-Server-4711" with id 10
> pkcs11-tool \
  --module opensc-pkcs11.so \
  --login \
  --pin 123456 \
  --keypairgen \
  --key-type EC:secp521r1 \
  --id 10 \
  --label "ECDH-Server-4711"

## read ssh key with id 08
> pkcs15-tool --read-ssh-key 08

## list all objects
> pkcs11-tool \
  --list-objects

## temporaly use key for host
> ssh -I /usr/lib64/pkcs11/opensc-pkcs11.so \
  user@example.com

## add key to ssh-agent
> ssh-add -s /usr/lib64/pkcs11/opensc-pkcs11.so

## if there is some trouble with "Could not open a connection to your authentication agent" use:
> eval "$(ssh-agent)"

## for ".ssh/config" usage
Host domain.tld
PKCS11Provider /usr/lib64/pkcs11/opensc-pkcs11.so

for detail to ECC see : zombiesecured.com

backup and restore

## create backup DKEK share
## important: DKEK have to be enabled on the initialyse
> sc-hsm-tool \
  --create-dkek-share dkek_share.pbe

## show created DKEK share
> openssl base64 -in dkek_share.pbe

## import DKEK share on a fresh key
> sc-hsm-tool \
  --import-dkek-share dkek_share.pbe

## backup a specific key
## search for "Key ref" in "pkcs15-tool -D"
> sc-hsm-tool \
  --wrap-key wrap_key.bin \
  --key-reference X \
  --pin 123456

## restore key
> sc-hsm-tool \
  --unwrap-key wrap_key.bin \
  --key-reference X \
  --pin 123456

delete stuff

## remove a created rsa privkey
> pkcs11-tool \
  --module opensc-pkcs11.so \
  --login --pin 123456 \
  --delete-object \
  --type privkey \
  --id 08

## remove a certificate
> pkcs11-tool \
  --module opensc-pkcs11.so \
  --login --pin 123456 \
  --delete-object \
  --type cert \
  --id 08

## remove data types
> pkcs11-tool \
  --module opensc-pkcs11.so \
  --login --pin 123456 \
  --delete-object \
  --type data \
  --label "Some Nice Label"

using openssl’s PKCS#11 support to manage certificates
first: setup a custom openssl config named as you like

# PKCS11 engine config
openssl_conf = openssl_def

[openssl_def]
engines = engine_section

[req]
distinguished_name = req_distinguished_name

[req_distinguished_name]

[engine_section]
pkcs11 = pkcs11_section

[pkcs11_section]
engine_id = pkcs11
dynamic_path = /usr/lib/engines-1.1/pkcs11.so
MODULE_PATH = /usr/lib/opensc-pkcs11.so
PIN = 123456 # if lazy > can also interactivly set
init = 0

in this case i named the file openssl-nitrokey.cfg
if you run in trouble with "/usr/lib/engines-1.1/pkcs11.so"
have a look at: https://github.com/OpenSC/libp11

try function

> OPENSSL_CONF=./openssl-nitrokey.cfg openssl engine

get a certificate sign request

> OPENSSL_CONF=./openssl-nitrokey.cfg \
  openssl req -engine pkcs11 \
  -keyform engine -new -key 0:15 -sha256 -out "x33u.org.csr" \
  -subj "/C=DE/ST=Sachsen-Anhalt/L=Magdeburg/O=x33u.org/OU=IT/CN=x33u.org"

or get a self signed certificate im PEM

> OPENSSL_CONF=./openssl-nitrokey.cfg \
  openssl req -engine pkcs11 \
  -keyform engine -new -key 0:15 -nodes -days 3560 -x509 -sha256 -out "x33u.org.pem" \
  -subj "/C=DE/ST=Sachsen-Anhalt/L=Magdeburg/O=x33u.org/OU=IT/CN=x33u.org"

create keys for own CA

> OPENSSL_CONF=./openssl-nitrokey.cfg \
  openssl req -engine pkcs11 \
  -keyform engine -new -key 0:15 -nodes -days 3560 -x509 -sha256 -out "master.pub.key" \
  -subj "/C=DE/ST=Sachsen-Anhalt/L=Magdeburg/O=x33u.org/OU=IT/CN=x33u.org"

0:15 means slotid:keyid
for a command reference see: dfn-cert.de