This is a quick cheatsheet for using Smallstep CA. It is not meant to be a comprehensive guide, but rather a quick reference for myself. It starts with the common tasks, but contains install and setup information as the end of the document.
Overview
This setup creates a Certificate Authority using the Smallstep CA, and a Nitrokey HSM 2 to protect the keying material.
I do this so that I can login to things like Opengear terminal servers, Dell iDRAC interfaces, Proxmox machines and similar without getting the annoying NET::ERR_CERT_AUTHORITY_INVALID error message from Chrome.
This really is not intended to replace more secure solutions, but instead as a convenience.
Note that the Smallstep support for the PKCS #11 is still a beta, and requires adding the step-kms-plugin as well as building a local copy of step-ca
My Certificates
Note: The numbers in the list match the id values in the PKCS#11 URIs used to create the keys and certificates.
Note: To sign with the RSA CA, see this section.
Common tasks
Signing a CSR
This will take a Certificate Signing Request and generate a certificate. In order to keep these organized I store them in ~/src/code/CA/certificates.
Because I am using the PKCS11 interface, I cannot use “offline” mode, and instead use the (locally compiled, with PKCS#11 support) step-ca program.
This means that I need to start Step CA, and then use step to actually sign the certificates. Don’t forget to stop step-ca after this. It is configured to only listen on 127.0.0.1:8100, so it’s not really the end of the world if I do forget, but…
- Start
step-ca - In another window:
step ca sign test.example.com.csr test.example.com.crtNOTE: This will prompt for a provisioner password. As this is only available locally, it is “password”. - Inspect the new certificate:
step certificate inspect --short test.example.com.crt - Stop
step-ca
Creating a certificate without a CSR
Sometimes devices don’t have an easy way to make a CSR, and instead expect you to make a key and certificate for them. If this is the case, step can create a key and CSR, and then use the above to sign it.
$ step certificate create --csr --san localhost --san example.com 192.0.2.1 test.example.com.csr test.kumari.net.key
Please enter the password to encrypt the private key:
Signing with the RSA CA
To sign with the RSA CA, you need to specify the CA and CA key when signing. This is because the default provisioner is configured to use the EC CA.
Start the step-ca with the RSA CA config:
step-ca ca-rsa.json
Then, when signing, specify the Root CA:
step ca sign --root "/Users/wkumari/.step/certs/root_ca_rsa.crt" nobby-drac.kumari.net.csr nobby-drac.kumari.net.pem
Inspecting a certificate
To inspect a certificate, you can use the step certificate inspect CLI tool. The basic command:
step certificate inspect --short test.example.com.crt
X.509v3 TLS Certificate (ECDSA P-256) [Serial: 2898...4074]
Subject: 127.0.0.1
localhost
macbook
Issuer: My Intermediate CA
Provisioner: This email address is being protected from spambots. You need JavaScript enabled to view it. [ID: Odw5...Aisg]
Valid from: 2026-03-08T08:43:38Z
to: 2036-03-05T08:44:38Z
Creating a bundle certificate, and decrypting a key
Some devices expect a bundle certificate, which contains the full chain of certificates. To create a bundle certificate, cat the files together. $ cat exmaple.kumari.net.pem ../SmallStep/certs/intermediate_ca_ec.crt ../SmallStep/certs/root_ca_ec.crt > exmaple.kumari.net.bundle.pem
Note: The order of the certificates in the bundle is important - the leaf certificate should be first, followed by the intermediate, and then the root.
To decrypt a key, use the step CLI tool:
example.kumari.net.decrypted.key```
### List issued certificates
To list issued certificates, you can use the `step-badger` CLI tool. This is a
third party tool, from
[step-badger](https://github.com/lukasz-lobocki/step-badger)
The basic command:
```bash
step-badger x509Certs ~/.step/db
Serial number Subject Start Finish Validity
302993289828619663782218509723082042948 CN=test.example.com 2026-03-08T04:05:50Z 2026-03-09T04:06:50Z Valid
288747816944534935195190911414687768787 CN=test.example.com 2026-03-08T04:06:41Z 2026-03-09T04:07:41Z Valid
Note: Because this uses the database, step-ca must be stopped.
Troubleshooting
Forgot to plug in the HSM
This bit me once - I fetched the HSM and connected the adapter - but forgot to actually connect the HSM to the adapter. The error message is clear though: error initializing PKCS#11: could not find PKCS#11 token
$ step-ca
badger 2026/03/29 20:04:08 INFO: All 1 tables opened in 0s
badger 2026/03/29 20:04:08 INFO: Replaying file id: 0 at offset: 20127
badger 2026/03/29 20:04:08 INFO: Replay took: 1µs
error initializing PKCS#11: could not find PKCS#11 token
OS X Update breaks PKCS#11
This is a known issue with OS X updates - see Nitrokey HSM Getting Started for more information.
Symptoms
$ step-ca
error initializing PKCS#11: could not find PKCS#11 token
$ pkcs15-tool -D
Using reader with a card: Nitrokey Nitrokey HSM
Failed to connect to card: Unresponsive card (correctly inserted?)
Solution
The problem can be fixed by either copying /usr/libexec/SmartCardServices to /usr/local/libexec/SmartCardServices
sudo mkdir -p /usr/local/libexec/SmartCardServices/drivers
sudo cp -a /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle /usr/local/libexec/SmartCardServices/drivers
Note: This is a known issue with OS X updates - see Nitrokey HSM Getting Started for more information.
Note: Ignore the errors from chown / permissions…
Setup and installation
Initializing the Nitrokey HSM
sc-hsm-tool --initialize --so-pin <16 char hex> --pin <6 char pin>
Printing the key info
$ pkcs15-tool -D
Using reader with a card: Nitrokey Nitrokey HSM
PKCS#15 Card [SmartCard-HSM]:
Version : 0
Serial number : DENKxxx
Manufacturer ID: www.CardContact.de
Flags :
PIN [UserPIN]
Object Flags : [0x03], private, modifiable
Auth ID : 02
[...]
Tries left : 3
PIN [SOPIN]
Object Flags : [0x01], private
ID : 02
[...]
Tries left : 15
Make things simpler
export PKCS_URI='pkcs11:module-path=/usr/local/lib/opensc-pkcs11.so;token=SmartCard-HSM;pin-value=<PIN>;id=1;object=root-ca-ec'
Creating the CA key
step kms create 'pkcs11:module-path=/usr/local/lib/opensc-pkcs11.so;token=SmartCard-HSM;pin-value=<KEY>;id=1;object=root-ca-ec'
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoKX9OFloafydMUzgJJkvE1iN7DQr
IPAE6BBgdXuWERsGWkpKx+79mPO8NwBs3Yjv+fRL2/RATvIOoaBthaX42g==
-----END PUBLIC KEY-----
Creating the Root Certificate
step certificate create --profile root-ca --not-after 219000h \
--kms
'pkcs11:module-path=/usr/local/lib/opensc-pkcs11.so;token=SmartCard-HSM;pin-value=<pin>;id=1;object=root-ca-ec'\
--key 'pkcs11:id=1;object=root-ca-ec' "Kumari Root EC CA" root_ca_ec.crt
This creates a root certificate with a 25 year validity (219000h)
Create the Intermediate Certificate
$ step kms create --kms "$PKCS_URI" "pkcs11:id=2;object=intermediate-ca-ec"
# And the certificate (also with 25 year life):
$ step certificate create --profile intermediate-ca --not-after 219000h \\
--kms "$PKCS_URI" \\
--ca-kms "$PKCS_URI" \\
--ca root_ca_ec.crt \\
--ca-key "pkcs11:id=1;object=root-ca-ec" \\
--key "pkcs11:id=2;object=intermediate-ca-ec" \\
"Kumari Intermediate EC CA" intermediate_ca_ec.crt
Setting defaults
# Defaults - 5year, max 10 year.
step ca provisioner update "This email address is being protected from spambots. You need JavaScript enabled to view it. " --x509-default-dur=43800h --x509-min-dur=5m --x509-max-dur=87600h
Creating the RSA Root Certificate
I needed to do this because some devices don’t support EC certificates, and instead require RSA. This is a bit more work, as the key generation is a bit more complex.
# Set the PKCS URI for the RSA key
xport PKCS_URI='pkcs11:module-path=/usr/local/lib/opensc-pkcs11.so;token=SmartCard-HSM;pin-value=<PIN>;id=3;object=root-ca-rsa'
# Create the key
step kms create --kty RSA --size 4096 'pkcs11:module-path=/usr/local/lib/opensc-pkcs11.so;token=SmartCard-HSM;pin-value=<PIN>;id=3;object=root-ca-rsa'
# Create the certificate (also with 25 year life):
step certificate create --profile root-ca --not-after 219000h \
--kms 'pkcs11:module-path=/usr/local/lib/opensc-pkcs11.so;token=SmartCard-HSM;pin-value=<PIN>;id=3;object=root-ca-rsa' \
--key 'pkcs11:id=3;object=root-ca-rsa' "Kumari Root RSA CA" root_ca_rsa.crt
# Create the intermediate key and cert.
step kms create --kty RSA --size 2048 --kms "$PKCS_URI" "pkcs11:id=4;object=intermediate-ca-rsa"
step certificate create --profile intermediate-ca --not-after 219000h \
--kms "$PKCS_URI" \
--ca-kms "$PKCS_URI" \
--ca root_ca_rsa.crt \
--ca-key "pkcs11:id=3;object=root-ca-rsa" \
--key "pkcs11:id=4;object=intermediate-ca-rsa" \
"Kumari Intermediate RSA CA" intermediate_ca_rsa.crt
