Windows-MY Problems
I'm trying to use the certificates out of the Microsoft Certificate Store to open a URLConnection that requires a client certificate.
Basically, I'm doing this-
KeyStore store = KeyStore.getInstance("Windows-MY");
store.load(null,null);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(store,null);
X509TrustManager tm =new NaiveTrustManager();
sc = SSLContext.getInstance("TLS");
TrustManager []tma ={tm};
sc.init(kmf.getKeyManagers(), tma,new SecureRandom());
Anyway, when I try this, I get the following error-
0000: 14 00 00 0C 4F 51 82 E855 95 73 AF FC A0 AB DE ....OQ..U.s.....
main, WRITE: TLSv1 Handshake, length = 32
main, waiting for close_notify or alert: state 1
main, Exception while waiting for close java.net.SocketException: Software caused connection abort: recv failed
If I create the KeyStore out of a P12 file instead of getting it from Windows-MY, it works. This P12 file is the same as the one I import into the Microsoft Certificate Store through IE.
Should creating a KeyStore out of Windows-MY work, or does it need to be a PKCS12? Any ideas?
Message was edited by:
Toshi47
[1507 byte] By [
Toshi47a] at [2007-11-27 8:48:35]

# 1
I've been encountering a similar issue.
Firstly, the way I've been configuring my program to use the SunMSCAPI provider is as follows:
System.setProperty("javax.net.ssl.keyStoreProvider",
"SunMSCAPI");
System.setProperty("javax.net.ssl.keyStore",
"Windows-MY");
System.setProperty("javax.net.ssl.trustStoreProvider",
"SunMSCAPI");
System.setProperty("javax.net.ssl.trustStore",
"Windows-ROOT");
SSL without client authentication works fine, but with client authentication it fails with a "Bad Key" error. I've traced this error to the following:
1. The SSL handshake reaches the Client Verification stage.
2. The server sends a message to client to be signed by the client's private key.
3. The client gets ready to sign the message. It gets the NONEwithRSA signature, which is a wrapper around the SunMSCAPI Cipher class to do raw RSA signing.
4. The client tries to sign the message via the cipher class, and the exception is thrown because Microsoft's Crypto API doesn't allow encrypting with private keys, only signing.
Now, while MD2, MD5 and SHA-1 signature classes are provided in the SunMSCAPI, I am not aware of a method to do raw RSA signing with it. So far the only way I've managed to get Client Authentication working is by setting the SunMSCAPI provider to use one of the other signature classes as the NONEwithRSA signature class, and setting the server to do the same - not a very elegant solution.
I'm far from an expert with JSSE and SSL though, so I'm quite likely missing something. The perfect solution would be a nice way to set what signature algorithm the client will use for the verification step in such a way that the client and server will both negotiate to use it, or else have a raw RSA signature class in the SunMSCAPI.
Message was edited by:
Immortius
# 3
> I'm pretty new at this, so I'm going to read up on a
> lot of what you said, but I have a question - how did
> you do this?
First, I note that I incorrectly said I was setting the "javax.net.ssl.keyStore" property to Windows-MY, I meant the javax.net.ssl.keyStoreType property (and likewise for the trustStore property).
Anyway, to change the Signature algorithm used by the client, I used code similar to the following:
Security.getProvider("SunMSCAPI").setProperty("Signature.NONEwithRSA", "sun.mscapi.RSASignature$SHA1");
On the server I had similar code loop though all the providers and if they had a Signature.SHA1withRSA property, copy its value to the Signature.NONEwithRSA property. I was using Tomcat as the server, and created a class that would do this when my server app started.