2

I'd like to obtain the user's identity from a smartcard (PKI) from a Java fat client on Windows with Sun's MSCAPIProvider. The target is:

  1. user opens the app
  2. prompted for card
  3. prompted for PIN
  4. I get the X509Certicate in Java
  5. grant access, etc.

I have found based on this stackoverflow question sample which list's all certs in MY store and I am able to sign some bytes with the Microsoft Smartcard Provider PIN prompt.

This is my code:

Provider provider = Security.getProvider("SunMSCAPI");
KeyStore store = KeyStore.getInstance("Windows-MY", provider);
store.load(null, null);

System.out.println(store);
Enumeration<?> aliases = store.aliases();
while(aliases.hasMoreElements()) {
    String alias = aliases.nextElement().toString();
    Certificate[] signerKey = (Certificate[]) store.getCertificateChain(alias);
    Object entry = store.getKey(alias, null);
    System.out.println(alias + " " + Arrays.toString(signerKey));
    System.out.println(entry);
}

Signature sig = Signature.getInstance("SHA1withRSA",provider);
PrivateKey key = (PrivateKey) store.getKey("Michael-O", null);

sig.initSign(key);
sig.update("Test".getBytes());
System.out.println(Arrays.toString(sig.sign()));

Now I am facing two problems:

  1. I do not know what his alias might be (chicken-egg-problem)
  2. How do I force PIN authorization with X509Cert as a result with establishing a SSL context though HTTPS?

Which are the missing bits?

Community
  • 1
  • 1
Michael-O
  • 18,123
  • 6
  • 55
  • 121
  • Have you tried filtering out the alias by requesting all the keys from the store? Have you tried adding a [CallbackHandler](http://docs.oracle.com/javase/7/docs/api/javax/security/auth/callback/CallbackHandler.html)? – Maarten Bodewes Mar 06 '13 at 00:29
  • 1. `PrivateKey entry = (PrivateKey) store.getKey(alias, null);` in a loop. With card the key is not printed. When I put in the card, the key is listed. Removing the card on the next run makes me ask for it. At no time I am asked to put in my PIN. 2. How is a CallbackHandler going too help me when I, 1. do not know the alias, 2. want to use the MS Smartcard Provider instead of a custom dialog? – Michael-O Mar 06 '13 at 08:40
  • You can request all key aliases from the KeyStore using `aliases()` and `isKeyEntry()`, maybe that will help retrieving the key? As for the CallbackHandler, if you get the PIN prompt probably depends on the implementation of the software that came with the smart card. I did not see any requirement that you want to use the provider's key prompt (and personally I would not want a PIN prompt outside the application - I like to know what I'm using the key for, but that's personal preference). – Maarten Bodewes Mar 07 '13 at 19:58
  • But is that seriously a solution by interating over the enumeration? – Michael-O Mar 07 '13 at 20:19
  • Well, logically, if you cannot register a listener of some kind to get a call back, there is little more you can to do than to poll (and retrieve more information if the polling result is not precise enough). – Maarten Bodewes Mar 07 '13 at 21:11
  • But why does the MS smartcard popup when I want to sign some bytes. So it must be possible. – Michael-O Mar 08 '13 at 21:39
  • Maybe there are two keys or two different handling methods for authentication and signing, but without more information I think we can only guess. – Maarten Bodewes Mar 08 '13 at 23:08
  • That makes sense, I will verify your ideas on monday and will reports. Thanks a lot. – Michael-O Mar 09 '13 at 09:52
  • I have no tried `isKeyEntry` and all entries are keys. So this does not help :-( – Michael-O Mar 12 '13 at 08:50

1 Answers1

1

For Windows case, normally smartcard vendors offers two drivers.

  • One to access and sign with the smartcard using the PKCS11 protocol.
  • Other one to access and sign using the Windows cryptographic service provider (aka CSP)

When you use the SunMSCAPI provider you can access the local user windows keystore and if there are some CSP smartcard drivers installed on it; you can also see the smartcard certificates through it (but you can not know the difference between local and smartcard ones since windows keystore acts as an interface).

If you try to access the public certificate of the smart card though sunMSCAPI you're accessing a public key so there is not need to introduce a PIN. However if you try to perform a signature, then the windows keystore delegates the operation to smartcard CSP which will prompt you for the PIN.

Now trying to answer your two specific questions:

  1. I do not know what his alias might be (chicken-egg-problem)

An option could be to print an info from all certificates (for example subject or serial number) in a popup (keeping the relation between alias and the description you show) an let user select what certificate want to use, and then internally you can use the alias to refer to the selected certificate; this is like any https authentication works when it required a client authentication; the browser shows you the possible certificates to authenticate with.

In https you can make some filters in the server to show only certificates which match some criteria (for example an apache you can filter certificates from some criteria; for example certificates issued for specific CA's) but finally the user have to select the desired one to perform authentication.

You can do also some kind of filter getting for example the certificate attributes or the certificate chain from the keystore and showing only which ones you think fit the requeriments... but finally if there is more than one after the filter you've to let the user decide which one want to choose.

  1. How do I force PIN authorization with X509Cert as a result with establishing a SSL context though HTTPS?

If you delegate the private key access operations to the smartcard CSP through the sunMSCAPI provider I think that you can don't care about the PIN, let the CSP take care of it for you.

If for some reason you need to keep the PIN then a possible option is to use a different provider (SunPKCS11) to instantiate directly the smartcard (not through CSP) and use the CallbackHandler (as @Maarten Bodewes suggest in the comments) to take care of it. However IMHO if in the scenario all the clients are on Windows I recommend you to use sunMSCAPI as you do to avoid problems with different PKCS11 driver implementations from some different smartcards.

albciff
  • 18,112
  • 4
  • 64
  • 89