If you're going to be using either a smart card or a network crypto provider, what you're likely to wind up with is a PKCS11 module for your platform. Sun provides for JCE a PKCS11 JCE Provider shim.
First, there is a very handy Spring idiom for adding providers to JCE at runtime. Here's how you can load BouncyCastle, for example, in a Spring application context as a throw-away bean (from this post at the SpringSource forums):
<property name="staticMethod" value="java.security.Security.addProvider"/>
You can add the PKCS11 provider in almost exactly the same way. The only change is how you declare the actual provider bean within the <list>:
<property name="modulePath" value="path/to/pkcs11/module"/>
The PKCS11ConfigFactoryBean's job is to spit out an InputStream, which it creates from a mock configuration file that it creates from various properties. You can check the PKCS11 provider's documentation for the complete list of the contents of the config file, but at the very least, it has to contain a line that says "library=path/to/pkcs11/module". After filling a
StringBufferwith the configuration options (don't forget to separate each line with \n), the getObject() method should return
Once you have the provider, you'll want to obtain a keystore. Your actual working code should be in the form of a bean that has a java.security.KeyStore property. You'll use the KeyStore to obtain the certificates and keys that are stored in the hardware. Spring provides the KeyStoreFactoryBean to fetch, load and initialize the keystore and plug it into your code. Just specify that you want a type "PKCS11" keystore and use the PIN as the password. You can then look up the certs and private keys and use them as normal. Of course, the
PrivateKeyobject you get back won't actually be the key - calling
getEncoded()on it, for example, won't work - it'll just be a sham object that provides a pointer to the actual key when it comes time to use it.