Using Smart Card as Keystore in Java, setup

Using a smart card as a key store promises stronger security compared to storing keys or certificates on a disk. This can be further improved by using a card reader with a PIN pad, an effective counter-measure against key loggers.

This article should provide basic information how to use smart card as key store for Java applications. You do not need an expensive card for such application - a cheaper, specialized crypto-card will do. The installation instructions in this article focus on Linux, as it is my preferred platform and the setup a bit more complicated than on Windows.

The stack

                PKCS11 provider
              PC/SC middleware
            USB smart card reader
                 smart card 

Installing Software
  1. Download a driver for your smart card reader from its producer's page and install it.
  2. Download and install PC/SC middleware - PCSC-Lite. It does not require  any configuration if you use USB reader.
  3. Get PKCS11 provider for your card. You can use open-source (OpenSC) or producer 's implementation, depending on which one works better with Java.

Setting PKCS11 Token for Java 

First you have to configure PKCS11 provider for Java. Open $JAVA_HOME/jre/lib/security/java.security and look for registered security providers - find lines starting with text security.provider. Add a new security provider by adding line security.provider.9=sun.security.pkcs11.SunPKCS11 /etc/pkcs11_java.cfg . Sun PKCS#11 provider allows integration of PKCS11 tokens with Java platform by interfacing a native library, usually delivered by the token producer.

The configuration file following the provider's fully qualified name may contain various PKCS11 settings. It usually contains only the three lines we can see in this setting for OpenSC:

name = OpenSC-PKCS11
description = SunPKCS11 via OpenSC
library = /usr/lib/opensc-pkcs11.so

The entry name serves as name of the PKCS11 provider and description is AFAIK optional. The most important is the library property, it contains a path to the PKCS11 implementation we want to use. 

Depending on environment in which the application will be used we would need  need to create a custom security policy,  the name of the provider is prefixed with "SunPKCS11-" :

grant { 
       permission java.security.SecurityPermission

In the second part we will see how to create key and certificate, load them into the card and use the key on card to sign and verify.


Basic Key/Certificates Manipulation by OpenSSL

Getting Server's SSL/TLS Certificate Chain

openssl s_client -connect some_hostname:443 -showcerts
X.509 certificates are dumped as base64-encoded strings between -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- headers. They should be (together with the headers) stored in files with .pem suffix.

We can look at the certificate information then:
openssl x509 -in cert.pem -inform PEM -noout -text

    Conversion of Key and Certificate Formats


    • PKCS1 – PEM to DER
      openssl rsa -in key.pem -out key.der -inform pem -outform der 

      The key format is reflected in the header (of the key.pem):


    • PEM to P12
      openssl pkcs12 -export -out cert.p12 -in cert.pem -inkey key.pem
    • PEM to DER
      openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER


    Setting Firefox Preferences via Selenium 2 (WebDriver API)

    I wanted to run Firefox from WebDriver with custom preferences.  So I looked into the well-known about:config for name of the option and, just to be sure, consulted About:config entries section of Mozilla Wiki.

    With the name of desired config option to change, the rest is a pieceof cake:

    FirefoxProfile profile = new FirefoxProfile();
    WebDriver webDriver =  new FirefoxDriver(profile);