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

Immortiusa at 2007-7-12 20:55:57 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 2

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?

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.

Toshi47a at 2007-7-12 20:55:57 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 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.

Immortiusa at 2007-7-12 20:55:57 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 4

We are having the same problem (see this thread: http://forum.java.sun.com/thread.jspa?threadID=5170899&tstart=-1). Did you find a way to set the signature algorithm used by the client for verification in such a way that the client and server negotiate and use it? We don't have control over the configuration of the server, so we need a client-side solution to the problem.

Thanks for any help - I'm glad to find others experiencing this problem...hopefully we can all figure it out.

dj242a at 2007-7-12 20:55:57 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 5

No, I don't think SSL allows this part to be negotiated. After further research I've found that what is happening is that a combination of MD5 and SHA-1 is being applied by JSSE, before and then NONEwithRSA is being used to finish the process.

Having browsed through SunMSCAPI's source code there is no way at present to use it for a raw RSA signing either.

Immortiusa at 2007-7-12 20:55:57 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 6
> the signature algorithm used by the client for verification... is determined by the signature embedded in the certificate when it was signed by the CA. It is not negotiated at all.
ejpa at 2007-7-12 20:55:57 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...