Skip to main content
Skip table of contents

Hardware Security Modules (HSM)

EJBCA SOFTWARE STACK

The information on this page applies only to the EJBCA Software stack. For details on which Hardware Security Modules (HSMs) are supported per deployment type, see the Interoperability - Supported Hardware Security Modules (HSMs) section.

EJBCA integrates with Hardware Security Modules (HSMs) through the following interfaces

  • REST-based APIs: Proprietary interfaces specific to each HSM.

  • PKCS#11: Standard interface managed by OASIS with two implementations:

    • PKCS#11 NG: The primary implementation in EJBCA Enterprise, offering greater control and early support for quantum-safe algorithms.

    • Java PKCS#11 (SunPKCS11): The implementation included in OpenJDK and most other JDKs. It exposes a Java keystore API but has significant limitations, restricting EJBCA to the capabilities supported by Java PKCS#11.

The following sections provide information about HSMs.

Available HSM Modules in EJBCA UI

For information about creating and using Crypto Tokens for HSMs, see Managing Crypto Tokens and Managing CAs.

When creating crypto tokens only create one crypto token for each slot/token on a HSM. Creating multiple crypto tokens for the same slot may result in issues. You can use the same crypto token in multiple CAs which is the supported approach.

In a software deployment of EJBCA, you can manage crypto tokens fully in the EJBCA CA user interface (UI) or CLI. The CA UI automatically lists the HSMs detected on your system.

When creating a new Crypto Token (Crypto Tokens>Create New) you can select between Soft and PKCS#11 crypto tokens. The PKCS#11 or PKCS#11 NG options are only available if EJBCA is able to find any known PKCS#11 modules in the file system.

If EJBCA finds known PKCS#11 modules in the file system, you can select PKCS#11 or PKCS#11 NG as Type. As PKCS#11 Library there is a list of the available known HSMs found in the file system.

If the PKCS#11 options are not available or your desired HSM is not in the list of available Libraries, there are a few options to configure:

  • To use Java PKCS#11 you must make the java PKCS#11 classes exportable. For more information, see Application Servers.

  • You can configure PKCS#11 modules that are not already known to EJBCA in conf/web.properties. See conf/web.properties.sample how to add new known modules and override existing (overriding should not be needed since you can add new locations with the same name).

The following sections describe the underlying operations and technical features of using HSMs and PKCS#11.

Configuring HSMs

Note that FIPS mode does not allow the same key to be used for signing and encryption.

The GUI configuration of CAs is backed by a properties field where properties unique to a particular CAs usage of the HSM is specified. All implemented HSM modules are using the same property keywords to define the identity and the purpose of the keys to be used. These keywords are:

  • certSignKey: Key used when signing certificates, can be RSA or ECDSA.

  • crlSignKey: Key used when signing CRLs, can be RSA or ECDSA.

  • keyEncryptKey: Key used for key encryption and decryption, this must be an RSA key.

  • testKey: Key used by HSM status checks, can be RSA or ECDSA.

  • hardTokenEncrypt: Key used for hardtoken encryption and decryption. PUK will be decrypted by this key.

  • defaultKey: Key used when no other key is defined for a purpose. If this is the only definition, then this key will be used for all purposes.

  • pin: Optional pin code used for auto-activation of a CA token, see below. Not recommended for high security set-ups, but very useful in some cases.

You may omit defaultKey if you want to be sure that the right key is used, but then all the other keys must be specified. It is recommended that the certificate and CRL signing keys are linked to the same key since different keys are rarely supported by verifying applications.

When implementing support for a new HSM the KeyStrings class could be used to manage the key properties described above. When it is an JCA/JCE API for the HSM it could also be wise to extend the BaseCAToken class.

The same activation code must be used for all keys used by a CA.

There are four additional key properties that can (optionally) be used when renewing CA keys and to produce roll-over certificates. Some of these (in particular the next keys) are only used when using API methods (such as WS).

  • previousCertSignKey : Alias of the previous signature key, as opposed to certSignKey which is the current signature key.

  • previousSequence: Sequence identifying the previous signature key, as opposed to the current sequence that is held in the CA token. This sequence will replace the current sequence in the caRef field when signing a request with the CAs previous key.

  • nextCertSigningKey: Alias of a new generated key on the HSM. When updating a CA signed by an external CA this is used to send a request, but the CA is still active using the old key. When the certificate response is received this key is activate and moved to certSignKey/crlSignKey.

  • nextSequence: Sequence identifying the next signature key.

Ttested HSMs are described below, with sample configurations and HSM specific documentation.

Using keys on Java PKCS#11 vs PKCS#11NG

When using the PKCS#11 crypto token type keys must be usable with the Java PKCS11 provider. For instance this means that the public key is read from a certificate object in the HSM and a public key object is not used. Consult the Java PKCS11 provider documentation for more information.

Using the PKCS11# NG crypto token, it can read keys generated with the Java PKCS11 provider but prefers to use private/public key objects which is a more common approach. Important attributes, except the ones needed for usage according to the PKCS#11 specification, are:

  • CKA_ID: must be the same in private and public key objects and is what binds the keys together

    • CKA_ID is used as the alias in the key list of the crypto token

  • CKA_LABEL: strictly not needed but set to pub-<alias> and priv-<alias> when generating keys with EJBCA or p11ng-cli.

PKCS#11 with Multiple HSM

The EJBCA software stack allows the use of multiple PKCS#11 HSMs simultaneously (for example, from different vendors). PKCS#11 have some limitations, such as that vendors typically allow only installing one instance of the PKCS#11 library per host system.

Multiple HSM usage is beneficial when different CAs or VAs use different HSMs or different HSM slots, configured as different independent Crypto Tokens in EJBCA. This is unrelated to HSM High Availability (HA). For HA capabilities, consult your HSM vendor’s documentation.

Possible configurations include:

  • Using multiple HSMs from different vendors (using different PKCS#11 libraries).

  • Using multiple tokens in the same HSM (in different EJBCA crypto tokens) when exposed as different tokens/slots in PKCS#11.

Limitations include:

  • Using multiple HSMs from the same vendor (using the same PKCS#11 library), unless the PKCS#11 library allows such configuration presenting the different HSMs as multiple tokens/slots to EJBCA.

  • Using the same token/slot with multiple EJBCA crypto tokens (you can merge crypto tokens if you have created several with the same configuration).

  • Using the same HSM / PKCS#11 library with both SunPKCS11 and P11NG at the same time (they may conflict).

Testing PKCS#11 keys for use by EJBCA

To test keys on the HSM for use by EJBCA, using the Java PKCS#11 provider, you can use the EJBCA Client Toolbox.

BASH
ant clientToolBox
cd dist/clientToolBox
./ejbcaClientToolBox.sh PKCS11HSMKeyTool test

The command gives further instructions about the parameters required, PKCS#11 library and slot.

Or with P11NG (Thales Luna example):

CODE
./p11ng-cli.sh listslots --lib-file /usr/safenet/lunaclient/lib/libCryptoki2_64.so
./p11ng-cli.sh showtokeninfo --lib-file /usr/safenet/lunaclient/lib/libCryptoki2_64.so --slot 0
./p11ng-cli.sh listobjects --lib-file /usr/safenet/lunaclient/lib/libCryptoki2_64.so --slot-ref SLOT_NUMBER --slot 0
./p11ng-cli.sh signperformancetest --lib-file /usr/safenet/lunaclient/lib/libCryptoki2_64.so --slot 0 --alias p256 --time-limit 5000 --signature-algorithm SHA256WithECDSA

Auto-activation of Crypto Tokens

The pin property is used to be able to automatically activate a CA token. The activation code may be specified in the property field with the keyword pin. If this property is not specified, then the CA has to be manually activated after each restart or re-deployment of EJBCA. Manual activation is done in the Admin GUI under Basic Functions > View Information or using the cli bin/ejbca.sh ca activateca.

The pin property can use a clear text password or an encrypted one.

BASH
pin foo123
pin 6bc841b2745e2c95e042a68b4777b34c

These two properties contain the same password. The obfuscated pin value can be obtained with the command bin/ejbca.sh encryptpwd:

BASH
$ bin/ejbca.sh encryptpwd foo123
Using JBoss JNDI provider...
Please note that this encryption does not provide absolute security, ....
Enter word to encrypt:
hidden
Encrypting pwd...
6bc841b2745e2c95e042a68b4777b34c

This encrypted password is not a high-security encryption. If the password.encryption.key property has not been customized it will not provide more security than just preventing accidental viewing since an EJBCA built-in encryption key is used. If an attacker gets hold of the encrypted password and the password.encryption.key has not been customized, the password can be decrypted using the source code of EJBCA.

HSMs and Post-Quantum Cryptographic Algorithms

Support for Post-Quantum cryptographic algorithms in HSMs is dependent on the support for the algorithms in the HSM and you need to confirm whether support is available. For more information on HSMs and Quantum Readiness, see Post-Quantum Cryptography Keys and Signatures.

HSMs and ECDSA

Support for ECDSA in HSMs are dependent on the support for the algorithm and specific curves in the HSM and you need to confirm whether support is available.

For more information on HSMs and ECDSA, see ECDSA Keys and Signatures.

PKCS11 Call Logging

If you use P11NG you can configure logging in JBoss/WildFly to log all PKCS#11 commands being done from the application to the HSM driver. Set debug logging on org.pkcs11.jacknji11.Cryptoki.

CODE
/subsystem=logging/logger=org.pkcs11.jacknji11.Cryptoki:add
/subsystem=logging/logger=org.pkcs11.jacknji11.Cryptoki:write-attribute(name=level, value=DEBUG)

Or when using the P11Ng CLI you can configure a log file for this in log4j.xml with something like this.

CODE
<!-- PKCS11 debug output -->
<appender name="pkcs11" class="org.apache.log4j.FileAppender">
    <param name="file" value="pkcs11.log" />
    <param name="append" value="false" />
    <param name="threshold" value="debug" />
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d{ISO8601} %-5p [%c{1}] - %m%n" />
    </layout>
</appender>
...
<category name="org.pkcs11.jacknji11.Cryptoki" additivity="false">
    <priority value="DEBUG"/>
    <appender-ref ref="pkcs11"/>
</category>

There are also other external tools available to sit as a man-in-the-middle to proxy and log all PKCS#11 calls.

You can debug PKCS11 sessions and all calls made, using OpenSC's P11Spy. As of EJBCA 6.8.0, P11Spy is by default included in the known P11 implementation in conf/web.properties.

Stop JBoss, install P11Spy, and set the environment variables used in the JBoss terminal:

CODE
apt-get install opensc-pkcs11
export PKCS11SPY=/usr/local/lib/softhsm/libsofthsm2.so
export PKCS11SPY_OUTPUT=logfile.log

Then start JBoss and create a new PKCS11 Crypto Token using the PKCS11Spy PKCS#11 Library.

Another option for PKCS#11 call logging is PKCS11-Logger. Using something like this example:

CODE
PKCS11_LOGGER_LIBRARY_PATH=/opt/utimaco/libcs_pkcs11_R2.so
PKCS11_LOGGER_LOG_FILE_PATH=/tmp/pkcs11_logger.log
PKCS11_LOGGER_FLAGS=64

And pointing EJBCA to use the PKCS11-Logger library pkcs-11-logger-x64_V2.2.0.so, don't forget to add it as a known P11 implementation in conf/web.properties (unless it's there already).

Remote Forwarding PKCS#11 using P11-Kit

P11-kit can be used to forward for example a USB Token HSM connected to your local laptop to a server running EJBCA. This allows you to have your HSM in your control, while running the server somewhere else, for example in the cloud. It requires some setup and some work when you disconnect/connect your token, but can work for low-scale deployments.

The following is an outline of commands to get a NitroKey HSM (connected to Local) available to a remote server (Remote) over P11-kit. EJBCA runs on the remote server. This is based on information by Maxence Mohr on PKI and HSM in a SME and remote-hsm, and tested on Ubuntu 16.04 and 18.04.

Install p11-kit on both Remote and Local

CODE
sudo apt install gcc make gtk-doc-tools help2man texinfo texlive-base libffi-dev libtasn1-dev gnutls-bin
wget https://github.com/p11-glue/p11-kit/releases/download/0.23.15/p11-kit-0.23.15.tar.gz
tar zxvf p11-kit-0.23.15.tar.gz
cd p11-kit-0.23.15/
./configure
make
make check
sudo make install
ls -al /usr/local/bin/p11-kit
ls -al /usr/local/lib/pkcs11/p11-kit-client.so

mkdir -p ~/.config/systemd/user
vi ~/.config/systemd/user/p11-kit-client.service
-----
[Unit]
Description=p11-kit client

[Service]
Type=oneshot
RemainAfterExit=true
RuntimeDirectory=p11-kit
ExecStart=/bin/true

[Install]
WantedBy=default.target
-----

systemctl --user daemon-reload
systemctl --user enable p11-kit-client.service
systemctl --user start p11-kit-client.service
ls /run/user/`id -u`/

Use SSH to forward P11 from Local to Remote

Run SSH from the machine where you plug your USB device (local) towards the server where you run EJBCA (remote).

CODE
# see https://github.com/fladna9/remote-hsm/blob/master/remote-hsm.sh

# Verifying if systemd user service is enabled (local).
systemctl --user status p11-kit-client.service | grep "Active: active"
# If _not_ running, start it
systemctl --user enable p11-kit-client.service
systemctl --user start p11-kit-client.service

# Verifying if systemd user service is enabled (remote). On Local:
ssh user@192.168.122.1 systemctl --user status p11-kit-client.service | grep "Active: active"
# If _not_ running, start it
ssh user@192.168.122.1 systemctl --user enable p11-kit-client.service
ssh user@192.168.122.1 systemctl --user start p11-kit-client.service

# On Local (with the USB Token), get tokenURL and start p11-kit server
p11tool --provider /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so --list-token-urls
(pkcs11:model=PKCS%2315%20emulated;manufacturer=www.CardContact.de;serial=DENK0101866;token=UserPIN%20%28SmartCard-HSM%29)
p11-kit server --provider /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so pkcs11:model=PKCS%2315%20emulated;manufacturer=www.CardContact.de;serial=DENK0101866;token=UserPIN%20%28SmartCard-HSM%29
(P11_KIT_SERVER_ADDRESS=unix:path=/run/user/1000/p11-kit/pkcs11-389; export P11_KIT_SERVER_ADDRESS;P11_KIT_SERVER_PID=390; export P11_KIT_SERVER_PID;)

eval P11_KIT_SERVER_ADDRESS=unix:path=/run/user/1000/p11-kit/pkcs11-389; export P11_KIT_SERVER_ADDRESS;P11_KIT_SERVER_PID=390; export P11_KIT_SERVER_PID;

# Done, local socket is at ${P11_KIT_SERVER_ADDRESS}

# SSH tunneling the socket to remote EJBCA instance. On Local:
ssh user@192.168.122.1 systemd-path user-runtime
(/run/user/1000)
ssh -N -f -R /run/user/1000/p11-kit/pkcs11:${P11_KIT_SERVER_ADDRESS#*=} user@192.168.122.1
# SSH tunneling done, remote socket is at 192.168.122.1:/run/user/1000/p11-kit/pkcs11

# Test remote access to token, from Local
ssh user@192.168.122.1 pkcs11-tool --module /usr/local/lib/pkcs11/p11-kit-client.so -L

If things fail and you have to start over, you need to clean sockets:

CODE
# On Local:
rm /run/user/1000/p11-kit/*
pkill -f p11-kit-server
pkill -f p11-kit-remote
pkill -f "ssh -N -f -R /run/user/"
# On Local (to Remote)
DISTANTRUN=$(ssh user@192.168.122.1 systemd-path user-runtime)
ssh user@192.168.122.1 rm "$DISTANTRUN/p11-kit"/*

HSM Vendor-specific Information

The following sections provide HSM vendor-specific installation and configuration information applicable to the EJBCA Software stack.

For a list of HSMs supported by the different EJBCA deployment types, see Interoperability and Certifications.

HSM vendor-specific installation and configuration information:

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.