I'm trying to connect to a secure webservice.
I was getting a handshake failure even though my keystore and truststore have been set correctly.
After several days of frustration, endless googling and asking everyone around I found out that the only problem was that java chose not to send the client certificate to the server during the handshake.
Specifically:
My questions:
I did manage to put together a dirty workaround for this, but I'm not very happy about it so I'll be glad if anyone can clarify this one for me.
The handshake allows the server to authenticate itself to the client by using public-key techniques, and then allows the client and the server to cooperate in the creation of symmetric keys used for rapid encryption, decryption, and tamper detection.
SSL-enabled client software always requires server authentication, or cryptographic validation by a client of the server's identity. The server sends the client a certificate to authenticate itself. The client uses the certificate to authenticate the identity the certificate claims to represent.
It's possible that you may have imported the intermediate CA certificate into the keystore without associating it with the entry where you have your client certificate and its private key. You should be able to see this using keytool -v -list -keystore store.jks
. If you only get one certificate per alias entry, they're not together.
You would need to import your certificate and its chain together into the keystore alias that has your private key.
To find out which keystore alias has the private key, use keytool -list -keystore store.jks
(I'm assuming JKS store type here). This will tell you something like this:
Your keystore contains 1 entry myalias, Feb 15, 2012, PrivateKeyEntry, Certificate fingerprint (MD5): xxxxxxxx
Here, the alias is myalias
. If you use -v
in addition to this, you should see Alias Name: myalias
.
If you don't have it separately already, export your client certificate from the keystore:
keytool -exportcert -rfc -file clientcert.pem -keystore store.jks -alias myalias
This should give you a PEM file.
Using a text editor (or cat
), prepare file (let's call it bundle.pem
) with that client certificate and the intermediate CA certificate (and possibly the root CA certificate itself if you want), so that the client-certificate is at the beginning and its issuer cert is just under.
This should look like:
-----BEGIN CERTIFICATE----- MIICajCCAdOgAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJVSzEa .... -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICkjCCAfugAwIBAgIJAKm5bDEMxZd7MA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNV .... -----END CERTIFICATE-----
Now, import this bundle back together into the alias where your private key is:
keytool -importcert -keystore store.jks -alias myalias -file bundle.pem
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With