Java client certificates over HTTPS/SSL Java client certificates over HTTPS/SSL java java

Java client certificates over HTTPS/SSL


Finally solved it ;). Got a strong hint here (Gandalfs answer touched a bit on it as well). The missing links was (mostly) the first of the parameters below, and to some extent that I overlooked the difference between keystores and truststores.

The self-signed server certificate must be imported into a truststore:

keytool -import -alias gridserver -file gridserver.crt -storepass $PASS -keystore gridserver.keystore

These properties need to be set (either on the commandline, or in code):

-Djavax.net.ssl.keyStoreType=pkcs12-Djavax.net.ssl.trustStoreType=jks-Djavax.net.ssl.keyStore=clientcertificate.p12-Djavax.net.ssl.trustStore=gridserver.keystore-Djavax.net.debug=ssl # very verbose debug-Djavax.net.ssl.keyStorePassword=$PASS-Djavax.net.ssl.trustStorePassword=$PASS

Working example code:

SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();URL url = new URL("https://gridserver:3049/cgi-bin/ls.py");HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();conn.setSSLSocketFactory(sslsocketfactory);InputStream inputstream = conn.getInputStream();InputStreamReader inputstreamreader = new InputStreamReader(inputstream);BufferedReader bufferedreader = new BufferedReader(inputstreamreader);String string = null;while ((string = bufferedreader.readLine()) != null) {    System.out.println("Received " + string);}


While not recommended, you can also disable SSL cert validation alltogether:

import javax.net.ssl.*;import java.security.SecureRandom;import java.security.cert.X509Certificate;public class SSLTool {  public static void disableCertificateValidation() {    // Create a trust manager that does not validate certificate chains    TrustManager[] trustAllCerts = new TrustManager[] {       new X509TrustManager() {        public X509Certificate[] getAcceptedIssuers() {           return new X509Certificate[0];         }        public void checkClientTrusted(X509Certificate[] certs, String authType) {}        public void checkServerTrusted(X509Certificate[] certs, String authType) {}    }};    // Ignore differences between given hostname and certificate hostname    HostnameVerifier hv = new HostnameVerifier() {      public boolean verify(String hostname, SSLSession session) { return true; }    };    // Install the all-trusting trust manager    try {      SSLContext sc = SSLContext.getInstance("SSL");      sc.init(null, trustAllCerts, new SecureRandom());      HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());      HttpsURLConnection.setDefaultHostnameVerifier(hv);    } catch (Exception e) {}  }}


Have you set the KeyStore and/or TrustStore System properties?

java -Djavax.net.ssl.keyStore=pathToKeystore -Djavax.net.ssl.keyStorePassword=123456

or from with the code

System.setProperty("javax.net.ssl.keyStore", pathToKeyStore);

Same with javax.net.ssl.trustStore