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.


  1. Rostislav,
    thanks for this useful post. I can't wait for the next part because I get stuck exactly on signing/verifying with a security token. I'm trying to sign and verify a data with the same token, but it fails somewhy.

    1. I'm glad you like my post. I do not know why your code fails, but I published my notes today, perhaps they will help you.