SSL with Windows Certificates

I'm not sure how easy this will be, but I'm trying to write a program that will connect to an HTTPS site with a personal certificate from the Windows certificate store. I chose to use Java for this because JSSE looked easy to use - not realizing that I'd be forced to use Java's certificate store.

I have no control over the server I'm connecting to, and it will only accept my smart card's certificates. These certificates are loaded into the Personal certificate store, but without the private key. Whenever a program needs the private key, the card reader software prompts me to enter a PIN (as the private key does not leave the card).

Can someone tell me the best way to make this work? Or is there a way to extract the complete certificate from the card?

[785 byte] By [Centrista] at [2007-11-26 13:29:32]
# 1

Looks to me that the problem can be reduced into 2 seperate issues: getting the smartcard to work so that you can read the stored certificates and private keys. And getting the https connection to work.

Java has smartcard support, but since there are several different kinds of cards available you'll have to check if your hardware is actually supported. A good place to start looking is here: http://java.sun.com/products/javacard/. There you can also grab the Java card development kit. The API docs are pretty self explaining here. Creating a card using Terminal.getCard and such. Although I have to add a small disclaimer since from what I read about the devkit its platform dependend. Not too sure but so far all my experience is based on the support supplied by Solaris 10 in combination with the cardreader on my Sun Blade 100. I could imagine that this might be a little different. But even then the API docs should provide you with most you need to know...

The next problem is then getting the https connection to go, IMO its the easiest of the two. Simply add the certificate you grabbed from the smartcard to a new keystore and use this as a trustmanager factory loaded with this keystore. You can then setup an SSLContext which you can then later use to setup an SSLSocket factory. Something in the likes of:

// using...

import java.security.KeyStore;

import javax.net.ssl.SSLContext;

import java.security.cert.Certificate;

import javax.net.ssl.TrustManagerFactory;

// setup keystore

/* Where 'cert' is naturally a reference to a Certificate(). */

KeyStore ks = KeyStore.getInstance("jks");

ks.load(null, null);

ks.setCertificateEntry("cardcert", cert);

// setup trustmanager

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

tmf.init(ks);

// Setup SSLContext with above trustmanager.

SSLContext sslcont = SSLContext.getInstance("SSL");

sslcont.init(null, tmf.getTrustManagers(), new SecureRandom());

You can then setup a HttpsURLConnection and use its SetSSLSocketFactory() method to point to the socketfactory from the created SSLContext. Hope this helps some.

Message was edited by: Lion-O

,,,to add the comment block so that 'cert' wasn't bungleing and a few import statements to make the example more clear ;)

Lion-Oa at 2007-7-7 20:34:02 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 2

Sorry for the late reply - very busy at work lately.

I didn't realize that Java supported smart cards, and I'll have to do some research to make sure my cards are supported (Axalto Access 64K). I did test several SSL examples I downloaded, and they worked fine - so I doubt I'll have a problem there.

Thankyou very much for your explanation. ;-)

Centrista at 2007-7-7 20:34:02 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...