JAVA Toolkit
| home | contact




isasilk with smartcards

We describe here how an iSaSiLk SSLv3/TLS client can use client authentication via an RSA smartcard or a similar device. Note that similar methods could be used to employ SSL 2.0 client authentication, server side RSA, or DH and DSS via a smartcard but there is currently no document describing this step by step. However, note that there is another document describing the iSaSiLk provider architecture in more detail.

The Steps in Detail

  1. Get yourself a smartcard that
    1. handles RSA signature creation operations. It should support keys at least 512 bits long (as always, 1024 bit or more recommended).
    2. can create signatures in PKCS#1 version 1.5 format, padding blocktype 1 (padding with 0xff). If your device cannot do that it has to be able to do raw (unpadded) RSA operations and you have to do the padding yourself. See the PKCS#1 specification available from http://www.rsa.com/rsalabs/node.asp?id=2125 for details.
    3. Accepts the finished hash to sign and does NOT do the hashing itself.
      If your device is unable to do any of that there is no way to use it with SSL.
  2. Get yourself a JCE compliant API to access the card. This means that the provider has to implement a subclass of  javax.crypto.CipherSpi (this is the standard way to do raw RSA operations in the JCE as defined by JavaSoft™). For iSaSiLk client authentication there will only be one operation be performed on the cipher after getCipher():
    signature = rsa.doFinal(hash);
    The doFinal() call must return the PKCS#1 formatted signature.
  3. Write and activate your own SecurityProvider. To avoid limitations of the JCE provider model iSaSiLk does not directly use getInstance() calls. Instead it uses subclasses of iaik.security.ssl.SecurityProvider. You have to write your own SecurityProvider. If you only want to use your own implementation of RSA and not change anything about the other algorithms the easiest way to do this is to is to subclass iaik.security.ssl.IaikProvider and to override the getCipher() method.
    For example:

    protected Cipher getCipher(String algorithm, int mode, Key key, AlgorithmParameterSpec spec, SecureRandom random) throws Exception {
      if( algorithm.equals(ALG_CIPHER_RSA_SIGN) == false ) {
        return super.getCipher(algorithm, mode, key, spec, random);
      }
      Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", myHardwareProvider);
      if( mode == CIPHER_ENCRYPT ) {
        rsaCipher.init(Cipher.ENCRYPT_MODE, key, spec, random);
      }
      return rsaCipher;
    }

    For more information about the iSaSiLk SecurityProvider model see the security provider site.

  4. Write your application. It is a standard iSaSiLk application, you only have to take care of two things. One, set your own SecurityProvider as the active cryptographic provider.
    Do this using, for example:
    SecurityProvider.setSecurityProvider(new mySecurityProvider());
    Two, add the respective credentials via clientContext.addClientCredentials(). The credentials consist of your certificate chain and a PrivateKey object.
    This of course cannot and will not be the actual private key as that is contained in the smartcard. Instead it can be an instance of an existing class containing dummy values or it can be your own subclass of PrivateKey containing information meaning e.g. use the second key on the first smartcard. For example, you might subclass the IaikProvider implementation to use the IAIK
    PCKS#11 provider for doing RSA
    based cipher operations only:

    package demo;
    public class MySecurityProvider extends IaikProvider {     
     protected Cipher getCipher(String algorithm, int mode, Key key, AlgorithmParameterSpec param, SecureRandom random) throws Exception {
        if (key instanceof IAIKPKCS11Key) {
          if (algorithm.startsWith(ALG_CIPHER_RSA)) {
            algorithm = ALG_CIPHER_RSA;
          }
          cipherEngine = Cipher.getInstance(algorithm, ((IAIKPKCS11Key) key).getTokenManager().getProvider().getName());
          if (mode != CIPHER_NONE) {
            int cmode = (mode == CIPHER_ENCRYPT) ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE;
            cipherEngine.init(cmode, key, param, random);
          }
        } else {
          cipherEngine = super.getCipher(algorithm, mode, key, param, random);
        }
     }
    }
  5. In this example above the key is an IAIKPKCS11Key instance that associates
    the Java™ key object with the actual PKCS#11 key object. In any case, that key
    object will only be used as a parameter to the cipher's init()
    method, no methods will be invoked on it by the library at all.

Once you have done that you are ready to go. All that remains is standard programming for iSaSiLk and
the Java™ platform, see the respective documentation for more information.

 

 
print    tip a friend
back to previous page back  |  top to the top of the page