I am trying to perform mutual authentication in Java. The structure of what I am trying to achieve is: server with self-signed certificate acts as a CA, signing the client certificate. Therefore, this is what I keep in each keystore/truststore:
Client:
Keystore:
Truststore:
Server
Keystore:
Truststore:
I am able to perform server's authentication, but when I enable setNeedClientAuth(true) on the server, I get the following errors at the log: http://pastebin.com/raw.php?i=P52Qq89z So the server seems to authenticate but the client cannot provide the CA chain, may it be an issue with the contents of its keystore?
I used openSSL to generate the keys and the certificates, KeyStore Explorer to create the keystores (after a couple of days of unsuccessful use of keytool) and JDK 1.7.0_51
UPDATE: the problem was solved following these instructions: https://stackoverflow.com/a/12150604/2891462 It was a problem with how the CA self-signed certificate had been created (only an issue in JDK 1.7, apparently).
There a couple of things that are wrong in your configuration.
Looking at your debugging logs, your certificate doesn't have the basic constraints to say CA=true.
[
Version: V1
Subject: CN=Ficticious bank, OU=SoE, O=University, L=London, ST=England, C=UK
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
Key: Sun RSA public key, 2048 bits
Validity: [From: Wed May 07 19:21:23 BST 2014,
To: Thu May 07 19:21:23 BST 2015]
Issuer: CN=Ficticious bank, OU=SoE, O=University, L=London, ST=England, C=UK
SerialNumber: [ 9a7143cf f5ecfbf8]
]
Algorithm: [SHA1withRSA]
...
]
It's not going to work as a CA if it's not a CA certificate. See RFC 3280 (and 5280):
This extension MUST appear as a critical extension in all CA certificates that contain public keys used to validate digital signatures on certificates.
Secondly, this certificate, which you also want to use as an End-Entity Certificate (EEC) for your server doesn't have a valid name for that server: no Subject Alternative Name and a CN that visibly doesn't match any host name. While the default SSLSocket
doesn't do any hostname verification by default (you can configure it), it's useful to have a valid host name for a server certificate, since clients should really verify it in principle.
Overall, there doesn't seem to be many benefits in using the very same certificate for the CA and the server certificate. Self-signed certificates are mainly useful when used on their own. If you're planning to use it as a CA certificate too, you might as well separate the CA certificate and the server certificate. It will certainly be useful in the long run, in particular when you have to change the server cert, on "Thu May 07 19:21:23 BST 2015" in your example, or if perhaps you need to re-issue the server cert for any other reason.
Beside this, you have the right idea for your keystore and truststore:
Client:
Keystore:
Truststore:
Server
Keystore:
Truststore:
for mutual authentication(2 way SSL) only 2 things needs to be done
server's certificate exported from server's keystore(not trust store - in case you are using different trust and key store)
and second is
client's certificate should be present in server's truststore(not key store - in case you are using different trust and key store)
additionally there is a good blog here to read about the same
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