It's not something that should happen by design, but for security concerns, i'm wondering how will the "right" certificate be sent to the server, assuming there are more than one certificates matching the requirement of being signed by a certain CA?
I'm using a simple SSL JAVA example client, connecting to an Apache HTTPD.
I tried testing with 4 certificates, each time deleting the chosen one and noting who was chosen next. I couldn't find a reasonable logic (i.e. date, alias name etc.) other than maybe a lexicographic order of the "sha256" of the certificates. that seems unlikely to me...
The example client does something like
System.setProperty("javax.net.ssl.keyStore","device.p12");
System.setProperty("javax.net.ssl.keyStorePassword","password");
System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");
System.setProperty("javax.net.ssl.trustStore","truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword","password");
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslSock = (SSLSocket) factory.createSocket("87.69.60.100",443);
BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(sslSock.getOutputStream(), "UTF8"));
wr.write("GET /lather HTTP/1.1\r\nhost: 87.69.60.100\r\n\r\n");
wr.flush();
And the Apache is configured with
SSLCACertificateFile rootCA.crt
SSLVerifyClient require
I couldn't find the relevant documentation to answer the question. I'm also wondering- is there any chance that the Apache will somehow forward more than one certificates chains? (say with a misbehaving client sending something weird).
Thanks!
Client Certificate Authentication is a mutual certificate based authentication, where the client provides its Client Certificate to the Server to prove its identity. This happens as a part of the SSL Handshake (it is optional).
Open the Windows Control Panel. Select Internet Options > Security tab > Custom Level. Select Enable for the “Don't prompt for client certificate selection when only certificate exists”
A server that requires client authentication will send a list of acceptable certificate types, possibly along with a list of acceptable CAs. By default, your Java client then applies the following algorithm:
The client certificate choice algorithm isn't specified in RFC 5246, but Java's simple default implementation seems reasonable, if subject to change in the future as noted by EJP. In particular, the 'first' one is pretty much random - credentials are currently stored in a Map
, so it is going to depend on iteration order of the entry set. Also, the KeyManager
implementations are pluggable, and there is a 'NewSun' implementation available with OpenJDK that is activated by passing the security property ssl.KeyManagerFactory.algorithm=NewSunX509
. This second one will also take into account of your client certificates' keyUsage and extendedKeyUsage attributes, as well as the expiry dates.
If you need to guarantee the certificate sent from a list of possibilities and you find that the default behaviours aren't doing it for you, your best option is to manually create a single-entry keystore and use it to initialise an SSLContext
, or write your own implemenation of X509KeyManager
to do what you want in chooseClientAlias
, like in the answers to this question or this question.
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