Token and Key Generation with SoftHSM: Integration with XCA and PKCS11 Tools
Token-side P-256 keys, an isolated ES256 signing service, server administration and the limits of Mac XCA connectivity, illustrated by the working identity demo.

What does SoftHSM solve?
SoftHSM is a software cryptographic store accessed through PKCS#11. In this project, it separates the issuer signing key from the main API and lets us test HSM-style key-use policies. Credentials and disclosure results use ES256 with a P-256 key generated in a token by a separate signing service.
This is not a hardware HSM deployment or a claim of certified physical key protection. Token files, PINs, backups and host access still need protection. The official SoftHSM project describes its software cryptographic-device approach and PKCS#11 interface.
Tokens, keys and applications are separate layers
- Token: The logical store for objects. The SO PIN supports administrative tasks, while the user PIN supports normal token operations.
- Key: A cryptographic object generated inside the token and selected by its label and object identifier.
- PKCS#11 module: The platform-specific library an application loads to access a token.
- Signing service: The component that uses the key for authorized calls. Business-policy enforcement remains a separate responsibility.
Create an isolated laboratory, not a new production token
The following Linux/Debian-family example uses a separate test store. Do not point it at a live token directory. Package names and module paths may vary by distribution.
sudo apt-get update
sudo apt-get install softhsm2 opensc
mkdir -p "$PWD/softhsm-lab/tokens"
cat > "$PWD/softhsm-lab/softhsm2.conf" <<EOF
directories.tokendir = $PWD/softhsm-lab/tokens
objectstore.backend = file
log.level = ERROR
EOF
export SOFTHSM2_CONF="$PWD/softhsm-lab/softhsm2.conf"
softhsm2-util --show-slots
softhsm2-util --init-token --free --label lab-issuer
Initialization prompts for PINs interactively. Supplying secrets directly with --pin or --so-pin may expose them through process arguments or shell history. Reinitializing a live token is not an inspection operation and can endanger existing keys.
Generate a P-256 key inside the token
If OpenSC’s pkcs11-tool is installed, the following example can be used after confirming the correct module path:
PKCS11_MODULE=/usr/lib/softhsm/libsofthsm2.so
pkcs11-tool --module "$PKCS11_MODULE" --list-slots
pkcs11-tool --module "$PKCS11_MODULE" \
--token-label lab-issuer --login \
--keypairgen --key-type EC:prime256v1 \
--id 01 --label issuer-lab-v1 \
--usage-sign --sensitive
pkcs11-tool --module "$PKCS11_MODULE" \
--token-label lab-issuer --login --list-objects
The example does not request --extractable. An application integration should explicitly set and validate CKA_SENSITIVE=true, CKA_EXTRACTABLE=false and CKA_SIGN=true. Our signer checks the policy on startup, tests that private-key value reads are rejected, and verifies a signature with the public key. The official OpenSC examples document tool and mechanism details.
Where does signing occur in the identity application?

Device and issuer signatures use separate keys in distinct trust boundaries.
- The API checks the institution account and its approved request template.
- The user selects fields on the iPhone and the device signs the request-bound challenge.
- The API validates the device signature with its public key, then checks the credential and transaction rules.
- The isolated service requests an ES256 signature from the issuer key in SoftHSM.
- The API verifies the returned issuer signature and delivers the result only to the owning institution.
The signer has no published external port. Only the signing service mounts the token volume. The main API receives neither token PINs nor the private key. A signer outage stops processing instead of switching to a development key. ES256 alone does not make this custom JSON contract a standard JWS or VC format.
Can XCA on a Mac access SoftHSM on the server?
XCA manages certificates and keys and can use tokens exposed through an appropriate PKCS#11 module. SoftHSM does not itself provide a remote network connection. Installing SoftHSM on a Mac and adding it to XCA creates a separate local token, not access to the server token. A Linux .so library also cannot be loaded directly on macOS.
An SSH tunnel alone does not turn a PKCS#11 library into a remote service. A compatible remote PKCS#11 layer or a vendor network-HSM client is a separate architectural choice. Our current signer API is not a general PKCS#11 provider that XCA can load. The XCA key documentation describes the relationship between token capabilities and provider modules.
Read-only inspection on the existing server
From an authorized SSH session, inspect slots and signer logs with:
docker exec kimlik-signer-1 softhsm2-util --show-slots
docker logs kimlik-signer-1 --tail 50
pkcs11-tool belongs to the separate OpenSC package; do not assume it is installed in the signer image. Prepare a controlled management environment for advanced operations. Token reset, key deletion, PIN changes and rotation must be coordinated with application configuration, backups and verification of earlier signatures.
Moving toward production
Persistent token selection and backups matter, but copying software token files is not equivalent to hardware-HSM backup assurance. Hardware migration requires validation of key generation, algorithms, signature encodings, access roles, rotation and recovery. An HSM controls private-key use; the application policy layer decides which institution may request which personal fields.
Standards and primary sources
Use the current editions and your organization’s approved policies when implementing production systems.
How would you rate this article?
Your feedback helps improve future articles.