Accessing SmartCard Certificates using PKCS#11

Many large corporations require two-factor authentications for their internal applications. This usually starts with the login to the office computer, e.g. using smartcards (or other tokens). In order to reasonably protect applications as well, they need to integrate the smartcard authentication. The following sample shows how to access the certificates located on the inserted smartcard using PKCS#11.

The PKCS#11 Configuration

In order to use the PKCS#11 API, a shared library compatible with the smartcard is necessary. With the given library, a configuration needs to be created first.

The name  key can be anything. The library key provides the path to the PKCS#11 library to load. The slot key represents the ID of the smartcard reader. This can be anything, but starts with 0. If only one smartcard reader is connected, the value is most-likely 0. An alternative to the slod ID would be slotListIndex.

PKCS#11 Provider Registration

Now with the prepared configuration, there are multiple ways to load it. The used implementation supports both, a file-path or an InputStream. So either locate it somewhere on the file-system, load it from the jar itself or dynamically create it at runtime, e.g. using a ByteArrayInputStream. The following example loads it from the jar.

Rather unusual in this sample is, it uses the restricted Sun-API as seen on line 2. This yields the requirement of the Oracle Java runtime (so no OpenJDK). Line 3 registers the instantiated PKCS#11 provider to the security context so it can be accessed whenever necessary.

The Callback Handler

In order to create a KeyStore with the smartcard, the password is necessary. One way would be providing the password right upon instantiation. But in this sample, a single sign-on approach is desired. This means, if the smartcard has already been unlocked (e.g. when unlocking the computer), no more password prompts are necessary. When working with callback handlers, the callback will only be fired if the information is required.

The example above will prompt for user’s password using the console. The line 12 will provide the password to the callback. If no password is given (e.g. the user cancels the login), null should be provided to the callback.

PKCS#11 KeyStore

With everything prepared, the KeyStore can finally be created. This is accomplished using the KeyStore.Builder.

Line 3 provides the previously created CallbackHandler to the KeyStore. There are multiple reasons KeyStore creation may fail. Two reasons for exceptions are an invalid password entry or no smartcard has been inserted into the reader at all.

Certificate Access

The now created KeyStore can be used just like any other KeyStore. The main difference is, that the keys are unextractable. But they still can be used for encryption tasks. The following sample shows how to iterate over all aliases and print the associated certificate.

Moreover, this KeyStore can also be used to prove identity to a remote host using SSL. But this may require selecting the correct alias prior the connection. This may be necessary because there is a high chance that there are multiple certificates located on the smartcard.

Example Code

References

2 thoughts on “Accessing SmartCard Certificates using PKCS#11”

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.