Getting a Java program to use a TLS MQ channel, and use an external USB keystore.

This project started off trying to get a java program to use an HSM (external keystore on a USB). This was not well documented, so I have documented my path.

I had set up my keystore on the USB HSM device as described here. This post covers the MQ side of it.

MQ provides some JMS samples.

I could use JmsBrowser using local bindings with the jms.sh script.

. /opt/mqm/java/bin/setjmsenv64
java -Djava.library.path=/opt/mqm/java/lib64 JmsBrowser -m QMA -d CP0000

To use a client channel (QMACLIENT) was easy, the program is configured to allow a channel name to be passed as a parameter using the -l option.

. /opt/mqm/java/bin/setjmsenv64
java -Djava.library.path=/opt/mqm/java/lib64 JmsBrowser -m QMA -d CP0000 -h localhost -p 1414 -l QMACLIENT

To use a TLS channel (QMAQCLIENTTLS) proved harder

. /opt/mqm/java/bin/setjmsenv64
java -Djava.library.path=/opt/mqm/java/lib64 JmsBrowser -m QMA -d CP0000 -h localhost -p 1414 -l QMAQCLIENTTLS

This gave me

CC=2;RC=2397;AMQ9641: Remote CipherSpec error for channel ‘QMAQCLIENTTLS’ to host ”. [3=QMAQCLIENTTLS]

It was hard to find where to specify the CipherSpec. The documentation said “Using the environment variables MQCHLLIB to specify the directory where the table is located, and MQCHLTAB to specify the file name of the table.” I tried this and got the same error.

I collected a trace using the Java option -Dcom.ibm.msg.client.commonservices.trace.status=ON , but the trace showed the cipher spec was null.

I gave up with this program and used an enhanced version of the program. JMS programs can use JNDI as a file repository of configuration information and the program can extract the information. For example you can configure Connection Factories(cf) which are MQ connections, and Q objects – which are queues.

Use JNDI to store parameters

JMS programs can use a JNDI interface to access configuration parameters stored in an external file.
I used this article to get me started.

My JMSAdmin.config had

INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactory
PROVIDER_URL=file:///home/colinpaice/mq/JNDI-Directory
SECURITY_AUTHENTICATION=none

I used the following commands to define a connection factory called CF1, using the channel, QMACLIENT, and a queue reference called MYQUEUE pointing to queue CP0000.

mkdir JNDI-Directory
/opt/mqm/java/bin/JMSAdmin -v -cfg JMSAdmin.config
define cf(CF1) transport(client) channel(QMACLIENT)
define q(MYQUEUE) queue(CP0000)
end

I used a bash script to run the program, using the JmsJndiBrowser sample (JmsBrowser with JNDI support).

. /opt/mqm/java/bin/setjmsenv64
java -Djava.library.path=/opt/mqm/java/lib64 JmsJndiBrowser -i file:///home/colinpaice/mq/JNDI-Directory -c CF1 -d MYQUEUE

This failed with

JMSCMQ0001: IBM MQ call failed with compcode ‘2’ (‘MQCC_FAILED’) reason ‘2400’ (‘MQRC_UNSUPPORTED_CIPHER_SUITE’).

Which was a surprise to me. I looked in the trace, and there was nothing obviously wrong. The channel was not configured for TLS.

I used the following command in the JMS Admin tool, to specify a TLS channel and configure the cipher suite

alter cf(CF1) channel(QMAQCLIENTTLS) SSLCIPHERSUITE(ANY_TLS12)

Note. If I displayed cf(CF1) it gave me SSLCIPHERSUITE(*TLS12).

This gave me unable to find valid certification path to requested target, which was good progress because it meant the cipher spec had been accepted.

I added in the Java parameters to identify the key store and trust store

. /opt/mqm/java/bin/setjmsenv64

kss=”-Djavax.net.ssl.keyStore=/home/colinpaice/ssl/ssl2/ecec.p12″
ksp=”-Djavax.net.ssl.keyStorePassword=password”
kst=”-Djavax.net.ssl.keyStoreType=pkcs12″
tss=”-Djavax.net.ssl.trustStore=/home/colinpaice/ssl/ssl2/dantrust.p12″
tsp=”-Djavax.net.ssl.trustStorePassword=password”
tst=”-Djavax.net.ssl.trustStoreType=pkcs12″
ks=”$kss $ksp $kst”
ts=”$tss $tsp $tst”

java $ks $ts -Djava.library.path=/opt/mqm/java/lib64 JmsJndiBrowser -i file:///home/colinpaice/mq/JNDI-Directory -c CF1 -d MYQUEUE

and it worked successfully.

Use the pkcs11 HSM external keystore.

I changed the file to specify the external keystore (with format pkcs11) on a USB device rather than a file on disk (format pkcs12).

kss=”-Djavax.net.ssl.keyStore=NONE”
kst=”-Djavax.net.ssl.keyStoreType=pkcs11″
ksp=”-Djavax.net.ssl.keyStorePassword=12345678″

but this gave

find /java.security.KeyStoreException: pkcs11 not found
java.security.NoSuchAlgorithmException: pkcs11 KeyStore not available

You have to tell Java where to find the pkcs11 code. This is configured in the java.security file. You can find it using find $JAVA_HOME/ -name java.security . This gave me the file name /usr/lib/jvm/java-8-oracle/jre/lib/security/java.security

It had the list of security providers,

security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=sun.security.ec.SunEC
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC

and is missing an entry for pkcs11.

You can edit this file, or override it. To override it, create a file like colin.java.properties with

security.provider.10=SunPKCS11 /home/colinpaice/mq/nitrokey.cfg

where

  • .10 is the next in sequence after the .9 in the java.security file
  • SunPKCS11 says use the Sun module.
  • /home/colinpaice/mq/nitrokey.cfg use this configuration file for the pkcs11 device.

Tell Java to use this override file, by using the Java option -Djava.security.properties=/home/colinpaice/mq/colin.java.properties.

The configuration file name for the pkcs11 is /home/colinpaice/mq/nitrokey.cfg with content

name = nitrokey
library = /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
slot=0

With these parameters the output from the JmsJndiBrowser command was

Initial context found!
Browse starts
No more messages
SUCCESS

Success – and it only took me half a day! The hardest part was known what to specify for the security.provider…… parameter.

Using the runmqakm commands and an HSM (but not strmqikm).

I tried to use strmqikm but it gave an exception.

You can use some of the runmqakm commands you know and love, to access a certificate with an HSM. For example

The command to list the database available to the runmqakm command,

runmqakm -keydb -list -crypto /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so

Gives

/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so : UserPIN (mytoken)

You can then use the token label UserPIN (mytoken) and password to use the key store, for example

runmqakm -cert -list all -crypto /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
-tokenlabel “UserPIN (mytoken)” -pw 12345678

gives

Certificates found
* default, - personal, ! trusted, # secret key
-	my_key3

and

runmqakm -cert -details -crypto /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
-tokenlabel “UserPIN (mytoken)” -pw 12345678
-label my_key3

displays the details of the certificate with label my_key3.

If the -tokenlabel was wrong or the -pw was wrong, I got the unhelpful messages

  • CTGSK3026W The key file “pkcs11” does not exist or cannot be read.
  • CTGSK2137W The label does not exist on the PKCS#11 device.

Create your certificate request

The following command create a new RSA private-public key pair and a PKCS10 certificate request. The documentation for runmqakm says it supports RSA. If you want to use an Elliptic Curve you will need to use an alternative method, for example openssl.

runmqakm -certreq -create -crypto /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
-tokenlabel “UserPIN (mytoken)” -pw 12345678
-dn “cn=colin,o=SSS” -file runmq.csr -label runmqlab -size 1024

Sign it

openssl ca -config openssl-ca-user.cnf -policy signing_policy -md sha256 -cert carsa1024.pem -keyfile carsa1024.key.pem -out runmq.pem -in runmq.csr

Store it back into the HSM keystore

I could not get the runmqakm command to receive the signed certificate and store it into the HSM keystore.

runmqakm -cert -receive -crypto /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so -tokenlabel “UserPIN (mytoken)” -file runmq.pem -pw 12345678

It failed with

CTGSK3034W The certificate request created for the certificate is not in the key database.

I could use

openssl x509 -inform pem -outform der -in runmq.pem -out runmq.der
pkcs11-tool –write-object runmq.der –type cert –label “runmqlab” -l –pin 12345678

The openssl command converts the file from .pem format, to .der format as .der format is required by pkcs11-tool.

Using strmqikm – the theory

If you want to use the strmqikm GUI, you have to configure the java.security file. For example edit /opt/mqm/java/jre64/jre/lib/security/java.security and add the next security.provider in the list.

security.provider.12=com.ibm.crypto.pkcs11impl.provider.IBMPKCS11Impl /home/colinpaice/mq/nitrokey.cfg

Where /home/colinpaice/mq/nitrokey.cfg is the configuration file, with

name = nitrokey
library = /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
slot=0

You can then use Ctrl+O, which brings up a pop up with “Key database type”. In this list should be PKCS11Config, if not check your java.security file. Select this, leave File Name and Location empty, and click “OK”. It pops up “Open Cryptographic Token” with the “Token Label” value taken from the configuration file name = nitrokey. This is strange as the runmqakm command uses a TokenLabel of “UserPIN (mytoken)”.

In practice…

I then got an exception java.lang.RuntimeException: PKCS11KeyStore.java: findSigner(): Failure while executing cobj.getX509Certificate(certFactory, session), and strmqikm ended.

Using a hardware security module USB as a keystore for a browser.

Background to certificates and keystores

When using TLS(SSL) you have two keystores

  • A keystore for holding the public part and private key of your certificate
  • A trust store which holds the public keys of certificate sent to you which you need to authenticate.

Your certificate has two parts

  • The private key which contains information needed to encrypt information you send. This needs to be kept private.
  • The public part,which has information that is needed to decrypt information you have encrypted, along with information such as your Distinguished Dame (DN) such as CN=ColinPaice C=GB,O=StromnessSoftware

The process of creating a signed certificate is

  • Create a private key and public key. This can be done using an external device Hardware Security Module (HSM), such as the Nitrogen HSM USB, or software, for example using OPENSSL. This produces a private key file, and a certificate request file containing the public information.
  • Send the public information to your certificate authority which signs it, and returns it
  • Import the signed public certificate into your keystore.

Creating a certificate using an HSM as the key repository

I used openssl to process my certificates, I’ve discussed the openssl setup here.

I use a bash script because it is easy to parametrize, and makes it easy to rerun until it works. I’ll give the script, then explain what it does

  • enddate=”-enddate 20240130164600Z”
  • name=”hw”
  • rm $name.key.pem
  • rm $name.csr
  • rm $name.pem
  • ca=”carsa1024″
  • pkcs11-tool –keypairgen –key-type rsa:2048 –login –pin 648219 –label “my_key3”
  • OPENSSL_CONF=eccert.config openssl req -new -engine pkcs11 -keyform engine -key label_my_key3 -out $name.csr -sha256 -subj “/C=GB/O=HW/CN=colinpaice” -nodes
  • openssl ca -config openssl-ca-user.cnf -policy signing_policy -md sha256 -cert $ca.pem -keyfile $ca.key.pem -out $name.pem -in $name.csr $enddate
  • openssl x509 -inform pem -outform der -in $name.pem -out $name.der
  • pkcs11-tool –write-object $name.der –type cert –label “my_key3” -l –pin 648219

What does the script do ?

enddate=”-enddate 20240130164600Z”

This sets the end date for the certificate – the end date is set when it is signed.

name=”hw”

This is used within the script to ensure the correct files are being used.

Remove old intermediate files
  • rm $name.key.pem
  • rm $name.csr
  • rm $name.pem
ca=”carsa1024″

Define the name of the CA files to use at signing time. The $ca.pem and $ca.key.pem are both needed.

pkcs11-tool –keypairgen –key-type rsa:2048 –login –pin 648219 –label “my_key3”
  • pkcs11-tool use this tool
  • –keypairgen to create a key pair (private and public pair)
  • –key-type rsa:2048 use this key type and key length
  • –login –pin 648219 login with the pin number
  • –label “my_key3” use this label to identify the key
OPENSSL_CONF=eccert.config openssl req -new -engine pkcs11 -keyform engine -key label_my_key3 -out $name.csr -sha256 -subj “/C=GB/O=HW/CN=colinpaice”
  • OPENSSL_CONF=eccert.config this sets up the openssl config file. Having -config eccert.config does not work. See here.
  • openssl
  • req this is to create a certificate requests – create a .csr.
  • -new it is a new request
  • -engine pkcs11 use the named engine, pkcs11, defined to the system
  • -keyform engine this says use the engine (HSM). Other choices are der and pem
  • -key label_my_key3 go to the engine and look for the my_key3 label
  • -out $name.csr create this request file with this name.
  • -sha256 using this signature
  • -subj “/C=GB/O=HW/CN=colinpaice” the name to go in the certificate. It uses colinpaice as the certificate will be used to authenticate with the mq web server, and this is the userid the mq web server should use.

Send the .csr file to the CA for signing (which is the same machine in my case).

openssl ca -config openssl-ca-user.cnf -policy signing_policy -md sha256 -cert $ca.pem -keyfile $ca.key.pem -out $name.pem -in $name.csr $enddate
  • openssl ca Use this command to sign the certificate
  • -config openssl-ca-user.cnf use this configuration file
  • -policy signing_policy use this policy within the config file
  • -md sha256 use this for the message digest
  • -cert $ca.pem use the public certificate of the CA
  • -keyfile $ca.key.pem use this private key of the CA to encrypt information about the csr request’s certificate
  • -out $name.pem whee to store the output
  • -in $name.csr the input .csr request
  • $enddate specify the certificate expiry date – set at the top of the script

Send the signed certificate back to the requester.b

openssl x509 -inform pem -outform der -in $name.pem -out $name.der

The pkcs11-tool uses .der files so convert the .pem file to .der format

  • openssl x509
  • -inform pem input format
  • -outform der output format
  • -in $name.pem hw.pem
  • -out $name.der hw.der
pkcs11-tool –write-object $name.der –type cert –label “my_key3” -l –pin 648219

Read the signed certificate and write it to the HSM

  • pkcs11-tool
  • –write-object $name.der write onto the HSM the file hw.der coverted above
  • –type cert import type (cert|pubkey|privkey)
  • –label “my_key3” use this name
  • -l –pin 648219 and logon with this pin number

Define the HSM to Chrome browser

Stop the browser because you need to update the keystore.
The command was issued in the home directory, because key store is in the home directory/.pki .

modutil -dbdir sql:.pki/nssdb/ -add “my_HSM” -libfile opensc-pkcs11.so

  • modutil use this command
  • -dbdir sql:.pki/nssdb/ to up date this keystore (in ~)
  • -add “my_HSM” give it this name
  • -libfile opensc-pkcs11.so and use this file to communicate to it

Display the contents of the browser’s keystore

modutil -dbdir sql:.pki/nssdb/ -list

This gave me

Listing of PKCS #11 Modules
 NSS Internal PKCS #11 Module
...
 Mozilla Root Certs
 library name: /usr/lib/x86_64-linux-gnu/nss/libnssckbi.so
...
my_HSM
 library name: opensc-pkcs11.so
    uri: pkcs11:library-manufacturer=OpenSC%20Project;library-description=OpenSC%20smartcard%20framework;library-version=0.17
  slots: 1 slot attached
 status: loaded
 slot: Nitrokey Nitrokey HSM (DENK01051600000         ) 00 00
 token: UserPIN (SmartCard-HSM)
   uri: pkcs11:token=UserPIN%20(SmartCard-HSM);manufacturer=www.CardContact.de;serial=DENK0105160;model=PKCS%2315%20emulated 

Restart the browser.

Use an URL which needs a certificate for authentication.

The browser prompts for the pin number (twice), and displays the list of valid certificate CNs. Pick one. When I connected to the mqweb server, I had 3 certificates displayed. I had to remember which one I wanted from the Issuer’s CN and serial number. For example

SubjectIssuerSerial
colinpaiceSSCARSA1024019c
ibmsys1SSCARSA1024019a
170594SSCARSA10240197
Select a certificate

(Having a CA just for HSM keys, such as SSSCAHSM would make it more obvious.)

Using openssl with an HSM keystore, and opensc pkcs11 engines.

A Hardware Security Module (HSM) is an external device, such as USB plugin which can securely store keystores, and do other encrpyption work. I used a Nitrokey which uses open source software.

Create the key on the HSM

pkcs11-tool –keypairgen –key-type EC:prime256v1 –login –pin 12345678 –label “my_key3”

Create the certificate request using openssl

To use the opensc pkcs11 driver for an HSM you need to pass parameters to the driver.

A typical openssl command to create a certificate request, using a pre existing private key, is

OPENSSL_CONF=hw.config openssl req -new -x509 -engine pkcs11 -keyform engine -key slot_0-label_my_key3 -sha256 -out hw.pem -subj “/C=CB/O=HW/CN=HW”

The fields for the HSM device are:

  • -engine pkcs11 . This tells openssl which exernal device to use. Use the command openssl engine -vvv -tt pkcs11 to display information about the pkcs11 engine
  • -keyform engine it needs to be “engine” to use the HSM.
  • -key xxxx where xxxx can be in the format
    • n:m where n is the slot number (“where the HSM device is plugged into – the first device is usually 0) and m is the id of the certificate, public key, or private key within the device
    • slot_n-id_m where where n is the slot number (“where the HSM device is plugged into – usually 0) and m is the id within the device
    • id_m m is the id within the device (slot_n defaults to slot_0)
    • slot_n-label_name where where n is the slot number (“where the hsm device is plugged into – usually 0) and name is the keyname within the HSM
    • label_name where name is the keyname within the HSM (and slot_n defaults to slot_0)

Note the id and labels are strings, so the id value 0100 is different from the value 100.

The command pkcs11-tool -O gave

Using slot 0 with a present token (0x0)
Public Key Object; RSA 2048 bits
  label:      Private Key
  ID:         0200
  Usage:      encrypt, verify, wrap
Public Key Object; RSA 2048 bits
  label:      my_key
  ID:         0100
  Usage:      encrypt, verify, wrap
Public Key Object; RSA 2048 bits
  label:      my_key2
  ID:         0101
  Usage:      encrypt, verify, wrap
Public Key Object; RSA 2048 bits
  label:      my_key3
  ID:         0fea4632d386a7f2469eec44daeafa84a1dbd8e2
  Usage:      encrypt, verify, wrap

So I could use for -key

  • 0:0100
  • id_0100
  • slot_0-id_100
  • slot_0-label_my_key
  • label_my_key

The code for this is here.

The contents of the openssl config file for HSM devices

I’ve displayed the bits you need for the “engine” or HSM processing.

openssl_conf = openssl_def

[openssl_def]
engines = engine_section

[engine_section]
pkcs11 = pkcs11_section
 
[pkcs11_section]
engine_id = pkcs11
dynamic_path = /usr/lib/x86_64-linux-gnu/engines-1.1/libpkcs11.so
MODULE_PATH    = /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
PIN = 648219
# init = 0

The documentation for the config file is https://www.openssl.org/docs/man1.1.1/man5/config.html .

The use of an HSM is driven from an “engine”.

The relevant statements in the config file are

  • openssl_conf openssl searches the config file for this entry by default. It describes which other sections should always be processed. If you use openssl req …, openssl will also process the section [req]. My file says use the section called openssl_def.
  • [openssl_def] this contains the names of sections to be processed. In this case it says process the engine_section.
  • [engine_section] this lists all of the engine sections to be processed. For a pkcs11 engine process I have called the section pkcs11_section.
  • [pkcs11_section] this lists the individual entries for the pkcs11 engine.
    • The engine_id is optional
    • The dynamic path is the code for the HSM. If specified, this must come first. For the default see openssl version -e or openssl version -a.
    • You can pass parameters through the HSM. Use the openssl engine -vvv -tt pkcs11 to list them. Note they are in upper case.
    • The MODULE_PATH in upper case is passed through to the device.
    • The PIN in upper case is passed through to the HSM. Without this, you are prompted for the pin
    • Using VERBOSE = EMPTY gives more information from the HSM device.

Problems using the config file.

The following command worked

OPENSSL_CONF=eccert.config openssl req -new -x509 -engine pkcs11 -keyform engine -key id_0101 -sha256 -out hw.pem -subj “/C=CB/O=HW/CN=HW”

The following command failed

openssl req -config eccert.config -new -x509 -engine pkcs11 -keyform engine -key id_0101 -sha256 -out hw.pem -subj “/C=CB/O=HW/CN=HW”

It looks like the config file is being processed twice, so you have to use the OPENSSL_CONF variable rather than the -config option.

The error messages are

  • engine “pkcs11” set.
  • Using configuration from eccert.config
  • Error configuring OpenSSL modules
  • engine routines:engine_list_add:conflicting engine id:../crypto/engine/eng_list.c :63. I think this is reporting it has already been processed and exists in the list of engines.
  • engine routines:ENGINE_add:internal list error:../crypto/engine/eng_list.c :223:
  • engine routines:dynamic_load:conflicting engine id:../crypto/engine/eng_dyn.c :502:
  • engine routines:int_engine_configure:engine configuration error:../crypto/engine/eng_cnf.c :141: section=pkcs11_section, name=dynamic_path, value=/usr/lib/x86_64-linux-gnu/engines-1.1/libpkcs11.so These are the parts of my configuration file.
  • configuration file routines:module_run:module initialization error:../crypto/conf/conf_mod.c: 174:module=engines, value=engine_section2, retcode=-1

Some other error messages

With no MODULE_PATH in the configuration file

  • engine “pkcs11” set.
  • No private keys found.
  • PKCS11_get_private_key returned NULL
  • cannot load Private Key from engine
  • pkcs11 engine:ctx_load_privkey:object not found:eng_back.c:876:
  • engine routines:ENGINE_load_private_key:failed loading private key:../crypto/engine/eng_pkey.c:78:
  • unable to load Private Key

Initial setup for using a keystore on a HSM USB stick.

You can use a keystore on disk, but this inherently insecure, as people with administrator access to the machine, can copy the keystore. Using an external device (such as a USB Hardware Security Module) as a keystore, is more secure as you need physical access to the machine to physically access the keystore. If you have 3 failed attempts to access the keystore using a PIN code, the device locks up.

I found this document a good high level introduction to smart keys.

This post describes the initial set up for using the Hardware Security Module from Nitrokey for securely storing my digital certificates. It comes as a USB device. I chose it because it cost under 80 euros. There are other suppliers, such as yubico , and other suppliers but either they did not supply a price, or it was “call us and to discuss it”.

I found the Instructions that came with it via here, and a user blog very useful.

The Nitrokey HSM is open sourced, and uses open source facilities.

Software needed to use the key.

My machine is Linux Ubuntu 18.04.
You need software installed to configure it.

sudo apt install opensc pcscd pcsc-tools

To be able to use openssl you need an “engine” interface.

sudo apt install libengine-pkcs11-openssl

Once install you need to start it

sudo systemctl start pcscd
sudo systemctl status pcscd

gives

● pcscd.service – PC/SC Smart Card Daemon
Loaded: loaded (/lib/systemd/system/pcscd.service; indirect; vendor preset: enabled)
Active: active (running) since Tue 2021-03-02 08:49:27 GMT; 2s ago

Display it (note it is two hypens)

opensc-tool ‐‐list‐readers

Gave me

#Detected readers (pcsc)
Nr. Card Features Name
0   Yes           Nitrokey Nitrokey HSM (DENK01051600000 ) 00 00

This shows the card is in

  • slot number 0. You may need this number when configuring keys, for example in openssl. This number is like a USB port number.
  • it is a physical card
  • it has no features listed
  • it comes from NitroKey and is a Hardware Security Module with the given serial number.

Set up

The device has

  • a device pin (SO-PIN) which is needed for administration, such as reinitialising the device or setting a user pin. This is 16 hex characters
  • a user pin to allow users access to modify keys. The user pin is a 6-15 digit string.

You need to consider how you use your device. You can have it self contained, and the private information is private to the device. This may be acceptable for a test device, but not in production, where you want to securely backup the keystore, and securely shared the key store between different machines. This can be done using Device Key Encryption Key (DKEK). The DKEK key is a 256-Bit AES key.

You can configure this so that you need more than one person to be able to enable a new device with this DKEK. You can configure n out of m people are needed. This is described here under Using key backup and restore.

You can use sc-hsm-tool – smart card utility for SmartCard-HSM, to

  • Initialize token, removing all existing keys, certificates and files.
  • Create a DKEK share encrypted under a password and save it to the file given as parameter.
  • Read and decrypt DKEK share and import into SmartCard-HSM
  • Define device pin for initialization
  • Force removal of existing key, description and certificate.
  • Define the token label to be used in –initialize.
  • Backup a private key to an encrypted external file. (Using the DKEK).
  • Restore a private key from an external encrypted file into the device, using the DKEK

You need to initialise the device see here.

I used

sc-hsm-tool –initialize –so-pin 3537363231383830 –pin 648219 –dkek-shares 1 –label mytoken
sc-hsm-tool –create-dkek-share dkek-share-1.pbe
sc-hsm-tool –import-dkek-share dkek-share-1.pbe

The command pkcs11-tool -L gave

Available slots:
Slot 0 (0x0): Nitrokey Nitrokey HSM (DENK01051600000         ) 00 00
  token label        : UserPIN (mytoken)
  token manufacturer : www.CardContact.de
  token model        : PKCS#15 emulated
  token flags        : login required, rng, token initialized, PIN initialized
  hardware version   : 24.13
  firmware version   : 3.4
  serial num         : DENK0105160
  pin min/max        : 6/15

The token label : UserPIN (mytoken) has the name I entered in the –label option above. When using MQ and GSKIT with this device,I needed to identify device with “UserPIN (mytoken)” not just “mytoken”.

You can create a private key using

pkcs11-tool –keypairgen –key-type rsa:2048 –id 10 –label “my_key”

Using slot 0 with a present token (0x0)
Key pair generated:
Private Key Object; RSA
label: Private Key
ID: 10
Usage: decrypt, sign, unwrap
Public Key Object; RSA 2048 bits
label: Private Key
ID: 10
Usage: encrypt, verify, wrap

You can omit the -id, and it will generate a (long) id for you. You can list the objects (in-use slots) in the device

pkcs11-tool -O

You can delete the one we just created

pkcs11-tool -l –pin 648219 –delete-object –type privkey –id 10

You can delete -type with privkey, pubkey and cert

Setting up digital certificates for identification in your enterprise.

You can use digital certificate for authentication, for example you can logon onto the MQ Web server using a certificate to identify you, and you do not have to enter a userid or password.

Many systems have Multi Factor Authentication (MFA) to logon which usually means you authenticate with something you have, and with something you know. Something you have is the private certificate, something you know is userid and password.

At the bottom I discuss having an external device for your keystore to make your keystore more secure.

General background and information

  • Your certificate has a private key (which should not leave your machine), and a public part, which anyone can have.
  • You can have a key store which has your private key in it. This is often just a file which could be copied to another machine. This is not a very secure way of keeping your certificates, as there is usually a stash file with the password in it, which could easily be copied along with the keystore.
  • You have a trust store which contains the public part of the certificates you want to validate (demonstrate trust) with. This is usually a set of Certificate Authority public keys, and any self signed certificates. The information in these certificates is commonly available and can be world read. You will want to protect this for write, so people cannot insert CAs from the bad guys.
  • You can use Hardware Security Module, a piece of hardware which can store your private keys, and does encryption for you. This is a secure way of keeping your certificates. You need physical access to the machine to be able to physically access the HSM hardware.
  • Certificates are based on trust. When I create a public certificate, I can get this signed by a Certificate Authority. When I send my public certificate to you, and you have the same Certificate Authority, you can check what I sent you using the Certificate Authority. My public certificate give information on how to decrypt stuff I send you.
  • When a connection is made between a client and a server. The server sends down its certificate for the client to validate and accept, and the client can then send up a certificate for the server to validate and accept. This is known as the handshake
  • A certificate has a Distinguished Name. This is like “CN=COLIN,OU=TEST,O=SSS.ORG” so my Common Name is COLIN, The Organizational Unit is TEST, and my Organization is SSS.ORG.
    • Some products like the mid-range MQ Web Server map the CN to a userid.
    • As part of the logon a client or server can check the certificate sent to it, for example allow any certificate with OU=TEST, and O=SSS.ORG.

Planning for TLS and certificate

Consider a simple scenario of two MQ Servers, and people from my.org and your.org want to work with MQ. Leaving aside the task of creating the certificate, you need to decide

  • What name hierarchy you want, for example CN=”COLIN PAICE”, OU=TEST, C=GB, O=SSS.ORG,
    • do you want to have a CN with a name in it, or a userid, or a personnel number. This is used by the MQWeb as a userid. You could have CN=MQPROD1, etc to give each server its own CN.
    • Do you want to have the country code in it C=GB? What happens if someone moves country. You might decide to have servers with CN=MQPROD1,OU=PROD… or OU=TEST… .
  • What CA hierarchy do you want. You could have a CA for OU=PROD, O=SSS.ORG at the PROD level, or CN=CA,O=SSS.ORG at the organisation level. Some servers can check the issuer is OU=PROD, O=SSS.ORG and so only allow certificates signed by that CA. Someone connecting with a certificate signed with OU=TEST,O=SSS.ORG would not be allowed access.
  • You could give each server the same DN, for example CN=MQSERVER,OU=PROD,O=SSS.ORG, or individual ones CN=MQSERVER1,OU=PROD,O=SSS.ORG
  • You can have a server check that a certificate is still valid by using Online Certificate Status Protocol (OCSP). After the handshake, a request goes to a remote server asking if the certificate is still valid. Ive written a blog post Are my digital certificates still valid and are they slowing down my channel start? z/OS does not support OCSP. MQ on z/OS supports a LDAP repository of Certificate Revocation Lists. If you intend to use OCSP you need to set up the OCSP infrastructure.
  • With the MQ mover, you can set up CHLAUTH records to allow or disallow DN’s or CA certificates.
  • The clients from my.org have a DN like CN=COLIN,OU=TEST,O=myorg.com. The clients from your.org have a DN like CN=170594,c=GB,o=your.org. You cannot have one string (SSLPEER) to allow both format certificates.
    • For connections to the chinit(mover) you can use CHLAUTH to give find grained control.
    • For the MQWeb on z/OS you can control which certificates (or Issuers) map to a userid.
    • For mid-range MQWEB you have no control beyond a successful handshake. CN=COLIN,o=MY.ORG, and CN=COLIN,o=YOUR.ORG would both map to userid COLIN even though they are from different organisations. The CN is used as a userid, and you map userids or groups to security profiles.

Setting up your certificates

As your private key should not leave your machine, the standard way of generating a certificate is

  • The client machine creates a certificate request. This has the public certificate, and the private key.
  • The public certificate is sent to the appropriate authority (a department in your organization) which signs the certificate. Signing the certificate consists of doing a check sum of the public certificate, encrypting the check sum value, and packaging the public certificate, the encrypted checksum, and the CA public certificate into one file. This file is sent back to the requester
  • The originator reads the package stores it in a keystore, and uses this as its public key.
  • Often this request for a certificate is allowed only when the machine is connected locally to the network, rather than over the internet. This means people need to bring their portable machines into the office to renew a certificate.

If you create the private certificate centrally and email it to the end user, someone who is snooping on the email will get a copy of it!

A machine can have more than one keystore and a keystore can have one or more certificates. With some servers you can configure the default certificate to use. If not they the “best” certificate is chosen. This could depend on the strength and selection of the cipher specs.

What if’s

Once you have set up your certificate strategy it is difficult to change it, so it is worth setting up a prototype to make sure the end to end solutions work, then throwing the prototype away and starting again.

You need to consider how to solve problems like

  • What if someone leaves my organisation, how do I inactivate the certificate
  • What happens of someone loses their laptop, how do I inactivate the certificate
  • Certificates have expiry dates. What do I need to do to renew the certificate before it expires – for example you could email the owner and tell them to bring the laptop to the office to renew the certificate
  • What happens if a CA expires?
  • Someone joins the department how do I update the access lists. Usually this is done using a repository like LDAP.
  • Are the CHLAUTH records restrictive enough to prevent the wrong people from getting access, but broad enough that you do not need to change them when someone joins the organisation.
  • What if you open up your business to a new organisation with a different standard of DN? What do you need to change to support it.

Use of physical keystores.

You can have a physical keystore to store your private key. This can range from a USB device up to integrated devices.
With these people cannot just copy the keystore and stash file, they need physical access to the device.

You need to plan how these will be used in your organisation for example you have two machines for HA reasons. Each has a USB store. Does each machine need its own private key? How do you handle disaster recovery when someone loses/breaks the keystore.

Physical keystores can have have a secure export and import capability. You configure a key onto the device, for example saying it needs 3 partial keys, needing three people to enter their portion of it. When you export the key, it comes out encrypted.

In this scenario the configuration process could be

  • Configure the first device. 3 people enter their password.
  • Create a private key
  • Export the private key and send it to the second machine. It is encrypted so can safely be sent.
  • Go to the second machine, and configure the second device.
  • As before, the three people have to configure the device.
  • Import the encrypted certificate to the device
  • Go the the next machine etc.
  • In some cases you can say that n out of m people are required to configure the device. So any 3 out of a team of 6 is enough.

Would you lock your front door and leave the key under the mat? So why do you do it with digital keys?

Where I live it is Island Mentality. Someone said to me that they do not lock their front door. Sometimes, when they come home, they find some eggs or tray-bakes on the kitchen table. They went on a celebration cruise, but could not find the key to the front door, and so left the house unlocked the two weeks they were away.

Digital certificates and keys are used for identification authentication. Often these are stored in a key store, just a file in Windows or Unix. You typically need a password to be able to read the file. If you got hold of a keystore, you could try “password” with an “o”, “passw0rd” with zero etc. There is no limit to the number of attempts you can have. Don’t worry, the password is stored in a stash file , which is just another file. If you have the key store and the stash file you can open the keystore using standard commands. Having both the keystore and the stash file is like finding the front door unlocked.

If someone is an administrator on the machine, they can access any file and so can get the keystore and the stash file. IBM says you need superuser access to install MQ – so the MQ administrator can access these files. I heard that one enterprise was doing backups from the user’s machines to a remote site. The files were encrypted at the remote site, but not the network link to the remote site – whoops! The files could have been stolen en route.

Use external security devices.

You can get round this problem by using an external Hardware Security Module. Instead of storing the keys in a file, they are stored on an external device. You can get USB like devices. Some HSM can store keys, other HSMs can encrypt data. For example my bank gives its user’s a small machine. You put in your debit card, enter your pin. It encrypts the data and generates a one time key which you enter into the bank’s web site.

To steal the keystore you now need access to the physical machine to be able to unplug the USB.

Built in devices that cannot be removed.

On some machines, such as z hardware, they have a tamper resistant “cryptographic chip” built in. If you remove it from the machine, it is useless. When you configure it you need three keys, so you have three people each with their own key. When you install the backup machine, the three people have to go on site, and re enter their keys. They have mechanisms like three wrong passwords and it self destructs (perhaps in a cloud of smoke, as it does in the movies).

“Cloud”

One of the selling points of cloud is flexibility. You can deploy an image anywhere; you can wheel in new machines, and wheel out old machines; and you can have different “tenants” on the same hardware. This makes it difficult to use an HSM device to store your keys, as each machine needs the same keys, and the HSM could have all the keys from all the tenants. So you have the problem, of having your key store as a file with its stash file, and even more people have access to these files.

Would you lock your front door and leave the key under the mat? So why do you do it with digital keys

It is all down to the management of risk. Digital certificates do not give absolute protection. Strong encryption just means it takes longer to crack!