I just finished playing with some nCipher’s HSM. Unfortunately there is no integration guide for OpenSSL that cover CHIL interface and nCipher hardware security modules.
nCipher’s installation guide is quite good, but after you finish installing hardware, drivers and daemons, you are on your own.
I found only two helpful sources: Andrea Campi’s blog entry about nCipher NetHSM and OpenSSL and Marek Marcola’s post on openssl-users mailing list.
Both guides ends on key generation and self-signed certificates. Its enough to get CHIL enabled application to work with nCipher’s HSM, but will not help you to convert any existing OpenSSL (not an CHIL-aware) application to use HSM.
CHIL enabled OpenSSL
When you have driver, hardserver and chil library for your HSM installed the next step is to install OpenSSL with CHIL support enabled. Modern Linux distribution may have CHIL already enabled. If so, there should be libchil.so library in /usr/lib/ssl/engines directory.
If libchil.so is missing follow OpenSSL installation steps as described in Apache2.2.x, OpenSSL 0.9.8x and nCipher Modules Integration Guide.
When OpenSSL in installed, add /opt/nfast/toolkits/hwcrhk to LD_LIBRARY_PATH:
$ export LD_LIBRARY_PATH=/opt/nfast/toolkits/hwcrhk
To check if OpenSSL is able to communicate with HSM trough CHIL interface run:
$ openssl engine -t chil (chil) CHIL hardware engine support [ available ]
If CHIL is available benchmark HSM with:
$ openssl speed rsa -engine chil -elapsed -multi 50
Hardware accelerated cryptography
Use engine interface to switch to cryptography implementation from hardware security module.
ENGINE *hwEngine = NULL;
if (!(hwEngine = ENGINE_by_id("CHIL")))
if (!ENGINE_set_default(hwEngine, ENGINE_METHOD_ALL))
When application finish its cryptography operations, it should free engine.
hwEngine = NULL;
Hardware key protection/storage
If you want to make your private keys more secure you should use hardware key protection (or even storage).
Hardware protected keys are stored on local filesystem, but encrypted by key stored only in HSM. To generate such key use:
$ /opt/nfast/bin/generatekey hwcrhk
Answer some questions (Protected by? module, Key type? RSA, Key size? 4096, Key identifier? keyname) and your encrypted (by module, as you choose in question above) private key is saved in /opt/nfast/kmdata/local/key_hwcrhk_rsa-keyname.
When using locally stored encryption keys you load them as in this example (I use EVP interface for high-level cryptographic functions):
fp = fopen("filename.key", "r");
if (fp == NULL)
pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
When you have CHIL keys, loading them is also very simple:
pkey = ENGINE_load_private_key(hwEngine, "rsa-keyname", NULL, NULL);
When key is no longer in use destroy it with:
If application just need to do some hardware accelerated RSA or it need to use hardware protected keys those code pieces along with CHIL-enabled OpenSSL is all you need.
7 thoughts on “nCipher HSM with OpenSSL”
Exactly what I was searching for. Thank you!
Can anyone send me a link where I can download the driver for NCipher HMS model nC4022W-150 please?
I have a running WindowsXp application that uses openssl (1.0.0d) to load softcard-protected private keys from an Ncipher Net-HSM.
Next step is loading ocs-protected keys.
I use the standard UI provided in openssl.
When calling ENGINE_load_private_key(), the ncipher nfhwcrhk library first calls the UI to get the passphrase
(e_chil.c::hwcrhk_get_pass) which works.
After introducing the correct passphrase, the nfhwcrhk asks to insert the smartcard (e_chil.c:hwcrhk_insert_card) and here it goes wrong. It does not detect that the card is in the slot (it is !) and keeps repeating the question.
Anybody has been there ? (and got further :-))
I have a nCipher hsm module. I am trying to use chil engine for my security operations. I followed your steps to load the private key, but ENGINE_load_private_key() fails.
How to figure out whats the issue is?
That link to Andrea Campi’s blog post is now 404. Maybe you can find it on archive.org, make it a PDF, and put it here?
Andrea Campi’s blog post ia available at archive.org:
In my code
ENGINE_by_id does not identify CHIL also tried with “chil”
(hwEngine = ENGINE_by_id(“CHIL”)) is always NULL
but the openssl say that chil is available as follows
# openssl engine -t chil
(chil) CHIL hardware engine support
[ available ]