hsmCompatVerify RSA EC Examples - dogtagpki/pki GitHub Wiki
This document demonstrates end-to-end RSA and EC private key archival and recovery using the hsmCompatVerify KRA simulator tool.
Key Points:
-
hsmCompatVerifyis a standalone KRA simulator - no CA/KRA instances needed -
Demonstrates traditional (non-PQC) key archival workflow
-
Uses RSA-2048 or EC (nistp256) for key generation
-
Tests both client-side and server-side operations
-
Supports HSM/PKCS#11 token testing
$ mkdir -p ~/demo/kra-compat/client-nssdb ~/demo/kra-compat/pkiserv-nssdb
$ cd ~/demo/kra-compat|
Note
|
All commands below assume you are in the ~/demo/kra-compat directory.
|
Initialize NSS security databases for both client and server.
# Create password file
$ echo "Secret.123" > client-nssdb/password.txt
# Initialize NSS database
$ certutil -N -d client-nssdb/ -f client-nssdb/password.txtThis step creates the necessary certificates for the KRA simulator. It only needs to be run once.
$ hsmCompatVerifyServ --setup-only \
--pkiserv-db-path pkiserv-nssdb \
--pkiserv-passwd-file pkiserv-nssdb/password.txt \
--hsm-token "" \
--hsm-token-passwd-file pkiserv-nssdb/password.txt \
--ca-nickname "test CA Signing Certificate" \
--transport-nickname "test KRA Transport Certificate" \
--storage-nickname "test KRA Storage Certificate" \
--verboseExpected Output:
-
RSA-4096 CA certificate created (self-signed)
-
RSA-2048 Transport certificate created
-
RSA-2048 Storage certificate created
-
PEM files exported to
pkiserv-nssdb/directory:-
kra_transport.pem -
kra_storage.pem
-
Verify:
$ ls -1 pkiserv-nssdb/*.pem
pkiserv-nssdb/kra_storage.pem
pkiserv-nssdb/kra_transport.pem
$ certutil -L -d pkiserv-nssdb
Certificate Nickname Trust Attributes
test CA Signing Certificate CTu,Cu,Cu
test KRA Transport Certificate u,u,u
test KRA Storage Certificate u,u,uGenerate an RSA-2048 user key pair and wrap it for archival using the KRA transport certificate.
$ hsmCompatVerifyClnt \
--client-db-path client-nssdb \
--client-passwd-file client-nssdb/password.txt \
--transport-cert pkiserv-nssdb/kra_transport.pem \
--output client-nssdb/test-rsa \
--algorithm RSA \
--key-length 2048 \
--keywrap-alg "AES KeyWrap/Wrapped" \
--rsa-keywrap RSA-OAEP \
--verboseExpected Output Files:
client-nssdb/test-rsa-wrapped-session.bin (256 bytes - RSA-OAEP wrapped session key)
client-nssdb/test-rsa-wrapped-private.bin (1224 bytes - AES-KWP wrapped RSA private key)
client-nssdb/test-rsa-public.der (294 bytes - RSA public key)Verify:
$ ls -lh client-nssdb/test-rsa-*
-rw-r--r--. 1 user user 294 client-nssdb/test-rsa-public.der
-rw-r--r--. 1 user user 1.2K client-nssdb/test-rsa-wrapped-private.bin
-rw-r--r--. 1 user user 256 client-nssdb/test-rsa-wrapped-session.binWhat Happened:
-
Client generated RSA-2048 key pair in NSS database
-
Generated 32-byte AES-256 session key
-
RSA private key wrapped with AES-256 session key using AES-KWP
-
Session key wrapped with KRA transport public key using RSA-OAEP
-
Three output files created for transmission to KRA
Unwrap the user’s private key from transport wrapping, re-wrap with storage key, and create LDIF entry.
$ hsmCompatVerifyServ \
--pkiserv-db-path pkiserv-nssdb \
--client-db-path client-nssdb \
--pkiserv-passwd-file pkiserv-nssdb/password.txt \
--hsm-token "" \
--hsm-token-passwd-file pkiserv-nssdb/password.txt \
--wrapped-session client-nssdb/test-rsa-wrapped-session.bin \
--wrapped-private client-nssdb/test-rsa-wrapped-private.bin \
--public-key client-nssdb/test-rsa-public.der \
--ca-nickname "test CA Signing Certificate" \
--transport-nickname "test KRA Transport Certificate" \
--storage-nickname "test KRA Storage Certificate" \
--subject-dn "CN=Test User RSA" \
--archive-only \
--ldif-file client-nssdb/kra-archived-key.ldif \
--keywrap-alg "AES KeyWrap/Wrapped" \
--rsa-keywrap RSA-OAEP \
--verboseExpected Output:
-
Session key unwrapped using transport private key (RSA-OAEP decryption)
-
RSA private key unwrapped successfully
-
New session key generated for storage wrapping
-
RSA private key re-wrapped with storage session key
-
Session key wrapped with storage public key
-
LDIF file created:
client-nssdb/kra-archived-key.ldif(contains certificate + wrapped key data)
Verify:
$ ls -lh client-nssdb/kra-archived-key.ldif
-rw-r--r--. 1 user user 4.8K client-nssdb/kra-archived-key.ldifWhat Happened:
-
KRA unwrapped session key using transport private key (RSA-OAEP)
-
User’s private key unwrapped from transport wrapping (AES-KWP)
-
User certificate generated and signed by CA
-
KRA generated new session key for storage
-
User’s private key re-wrapped for long-term storage (AES-KWP)
-
Session key wrapped with storage public key (RSA-OAEP)
-
LDIF entry created containing certificate and wrapped key metadata
Read archived key from LDIF, unwrap with storage key, and export to PKCS#12 file for user.
$ hsmCompatVerifyServ \
--pkiserv-db-path pkiserv-nssdb \
--client-db-path client-nssdb \
--pkiserv-passwd-file pkiserv-nssdb/password.txt \
--hsm-token "" \
--hsm-token-passwd-file pkiserv-nssdb/password.txt \
--ldif-file client-nssdb/kra-archived-key.ldif \
--ca-nickname "test CA Signing Certificate" \
--transport-nickname "test KRA Transport Certificate" \
--storage-nickname "test KRA Storage Certificate" \
--p12-output client-nssdb/recovered-user-rsa.p12 \
--recovery-passwd "Secret.123" \
--recover-only \
--verboseExpected Output:
-
Loaded certificate + wrapped keys from LDIF
-
Session key unwrapped using storage private key (RSA-OAEP decryption)
-
RSA private key unwrapped successfully
-
PKCS#12 file created:
client-nssdb/recovered-user-rsa.p12
Verify:
$ ls -lh client-nssdb/recovered-user-rsa.p12
-rw-------. 1 user user 2.8K client-nssdb/recovered-user-rsa.p12What Happened:
-
KRA loaded archived key entry from LDIF
-
KRA unwrapped session key using storage private key (RSA-OAEP)
-
User’s private key unwrapped from storage (AES-KWP)
-
PKCS#12 file created with user’s certificate and private key
-
PKCS#12 encrypted with AES-256-CBC + PBKDF2 (default non-legacy mode)
$ pk12util -l client-nssdb/recovered-user-rsa.p12 -W Secret.123Expected Output:
Key(shrouded):
Friendly Name: CN=Test User RSA
Encryption algorithm: AES-256-CBC
Parameters:
Iteration Count: 10000 (from PBKDF2)
IV: [16 bytes]
Certificate:
Data:
Subject: "CN=Test User RSA"
Issuer: "CN=test CA Signing Certificate"
Serial Number: ...
Public Key Algorithm: RSA
Public Key Size: 2048 bitsImport the recovered PKCS#12 file into a fresh database to verify round-trip success.
# Create fresh test database
$ mkdir -p test-import
$ echo "Secret.123" > test-import/password.txt
$ certutil -N -d test-import -f test-import/password.txt
# Create p12tool password file
$ echo "Secret.123" > p12.pwd
# Import PKCS#12 using p12tool
$ p12tool -i client-nssdb/recovered-user-rsa.p12 \
-d test-import \
-w p12.pwd \
-k test-import/password.txt
# Verify import
$ certutil -L -d test-import
$ certutil -K -d test-importExpected Result:
PKCS12 IMPORT SUCCESSFUL
Certificate and private key imported successfully
$ certutil -L -d test-import
Certificate Nickname Trust Attributes
CN=Test User RSA u,u,u
test CA Signing Certificate ,,
$ certutil -K -d test-import
< 0> rsa xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx CN=Test User RSAYou can also test EC key archival by changing the algorithm:
$ hsmCompatVerifyClnt \
--client-db-path client-nssdb \
--client-passwd-file client-nssdb/password.txt \
--transport-cert pkiserv-nssdb/kra_transport.pem \
--output client-nssdb/test-ec \
--algorithm EC \
--curve nistp256 \
--keywrap-alg "AES KeyWrap/Wrapped" \
--rsa-keywrap RSA-OAEP \
--verboseExpected Output Files:
client-nssdb/test-ec-wrapped-session.bin (256 bytes)
client-nssdb/test-ec-wrapped-private.bin (48 bytes - EC private key is smaller)
client-nssdb/test-ec-public.der (91 bytes - EC public key)# Archive
$ hsmCompatVerifyServ \
--pkiserv-db-path pkiserv-nssdb \
--client-db-path client-nssdb \
--pkiserv-passwd-file pkiserv-nssdb/password.txt \
--hsm-token "" \
--hsm-token-passwd-file pkiserv-nssdb/password.txt \
--wrapped-session client-nssdb/test-ec-wrapped-session.bin \
--wrapped-private client-nssdb/test-ec-wrapped-private.bin \
--public-key client-nssdb/test-ec-public.der \
--ca-nickname "test CA Signing Certificate" \
--transport-nickname "test KRA Transport Certificate" \
--storage-nickname "test KRA Storage Certificate" \
--subject-dn "CN=Test User EC" \
--archive-only \
--ldif-file client-nssdb/kra-archived-key-ec.ldif \
--keywrap-alg "AES KeyWrap/Wrapped" \
--rsa-keywrap RSA-OAEP \
--verbose
# Recover
$ hsmCompatVerifyServ \
--pkiserv-db-path pkiserv-nssdb \
--client-db-path client-nssdb \
--pkiserv-passwd-file pkiserv-nssdb/password.txt \
--hsm-token "" \
--hsm-token-passwd-file pkiserv-nssdb/password.txt \
--ldif-file client-nssdb/kra-archived-key-ec.ldif \
--ca-nickname "test CA Signing Certificate" \
--transport-nickname "test KRA Transport Certificate" \
--storage-nickname "test KRA Storage Certificate" \
--p12-output client-nssdb/recovered-user-ec.p12 \
--recovery-passwd "Secret.123" \
--recover-only \
--verbose-
Client generates RSA or EC key pair
-
Client wraps private key using KRA transport public key (RSA-OAEP + AES-KWP)
-
KRA archives by unwrapping with transport and re-wrapping with storage key
-
KRA recovers by unwrapping from storage and exporting to PKCS#12
-
RSA-OAEP: Session key wrapping with transport/storage public keys
-
AES-256-KWP: Private key wrapping (RFC 5649, FIPS-compliant)
-
PBKDF2 + AES-256-CBC: PKCS#12 encryption (non-legacy mode)
This demo uses --keywrap-alg "AES KeyWrap/Wrapped" (AES-KWP, RFC 5649) which is recommended for FIPS compliance.
Available Key Wrap Modes:
| Algorithm | Description | PKCS#11 Mechanism |
|---|---|---|
|
AES-256-KWP (RFC 5649) |
CKM_AES_KEY_WRAP_KWP (0x210B) |
|
AES-256-KWP (alternative) |
CKM_AES_KEY_WRAP_PAD (0x210A) |
|
AES Key Wrap (8-byte aligned) |
CKM_AES_KEY_WRAP (0x2109) |
|
AES-CBC with IV |
CKM_AES_CBC_PAD (0x1085) |
Important: The same --keywrap-alg must be used in both hsmCompatVerifyClnt and hsmCompatVerifyServ.
This demo uses --rsa-keywrap RSA-OAEP which is recommended for better security.
Available RSA Wrap Modes:
| Mode | Description |
|---|---|
|
RSA-OAEP (recommended, better security) |
|
RSA PKCS#1 v1.5 (legacy compatibility) |
Important: The same --rsa-keywrap must be used in both hsmCompatVerifyClnt and hsmCompatVerifyServ.
The tool supports HSM/PKCS#11 token testing by specifying the HSM token name:
$ hsmCompatVerifyServ --setup-only \
--pkiserv-db-path pkiserv-nssdb \
--pkiserv-passwd-file pkiserv-nssdb/password.txt \
--hsm-token "MyHSM" \
--hsm-token-passwd-file hsm-password.txt \
--ca-nickname "test CA Signing Certificate" \
--transport-nickname "test KRA Transport Certificate" \
--storage-nickname "test KRA Storage Certificate" \
--verboseThis will create CA, transport, and storage keys on the HSM token named "MyHSM".
$ hsmCompatVerifyServ \
--pkiserv-db-path pkiserv-nssdb \
--client-db-path client-nssdb \
--pkiserv-passwd-file pkiserv-nssdb/password.txt \
--hsm-token "MyHSM" \
--hsm-token-passwd-file hsm-password.txt \
--wrapped-session client-nssdb/test-rsa-wrapped-session.bin \
--wrapped-private client-nssdb/test-rsa-wrapped-private.bin \
--public-key client-nssdb/test-rsa-public.der \
--ca-nickname "test CA Signing Certificate" \
--transport-nickname "test KRA Transport Certificate" \
--storage-nickname "test KRA Storage Certificate" \
--subject-dn "CN=Test User RSA" \
--p12-output client-nssdb/recovered-user-rsa.p12 \
--recovery-passwd "Secret.123" \
--verboseIssue: hsmCompatVerifyServ or hsmCompatVerifyClnt not found
Solution: Ensure tools are in PATH or use full path to binaries
Issue: Transport certificate not found
Solution: Verify the transport certificate was exported during setup:
$ ls -l pkiserv-nssdb/kra_transport.pemIssue: PKCS#12 import fails
Solution: Verify password and database are correct. Use p12tool for importing PKCS#12 files.
Issue: Key wrap algorithm mismatch
Solution: Ensure the same --keywrap-alg is used in both client and server commands
Issue: RSA keywrap type mismatch
Solution: Ensure the same --rsa-keywrap is used in both client and server commands
By default, hsmCompatVerifyServ creates non-legacy PKCS#12 files using AES-256-CBC + PBKDF2. For compatibility with older systems, you can use legacy format:
$ hsmCompatVerifyServ \
--recover-only \
--ldif-file client-nssdb/kra-archived-key.ldif \
--p12-output client-nssdb/recovered-user-legacy.p12 \
--recovery-passwd "Secret.123" \
--legacyPKCS12 \
--verboseThis will create a PKCS#12 file using PBE_SHA1_DES3_CBC (not FIPS-compliant).