Hello,

After my first post concerning the SSL and the tool PorteCle (http://www.javablog.fr/java-ssl-generate-keystore-self-signed-certificate-tool-portecle.html) allowing the generation of KeyStore, self-signed certificate instead of Keytool supported in the JDK / JRE, I would like to present a new tool KeyStore Explorer.

KeyStore Explorer is an open source GUI replacement for the Java command-line utilities keytool and jarsigner. KeyStore Explorer presents their functionality, and more, via an intuitive graphical user interface.

https://keystore-explorer.org/

https://keystore-explorer.org/downloads.html


JAVA CACERTS truststore

First, a truststore is used to authenticate peers. A keystore contains private keys of the clients and is used to authenticate yourself.

So, there is also a truststore ‘cacerts‘ used to authenticate the java process executed in JVM using the JDK. Java stores in this truststore the public certificates of root CAs. Java uses cacerts to authenticate java processes with remote servers (example during a proxies generation via WSDL). You could add the certificat of remote servers in the ‘cacerts‘ truststore.

The Java ‘cacerts‘ truststore is a file accessible in the folder $JAVA_HOME\jre\lib\security (ex: C:\SDK\jdk1.X.Y_ZZ\jre\lib\security).


It is protected by a default password (ex: “changeit” or “changeme”) which could be modified by the following commands:

Add -storepass to keytool arguments.
$JAVA_HOME/bin/keytool -storepasswd -storepass '' -keystore mykeystore.jks

But also notice that -list command does not always require a password. I could execute follow command in both cases: without password or with valid password

$JAVA_HOME/bin/keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts


Disable Certificate Validation in Java SSL Connections

An other solution could be disable Certificate Validation in Java SSL Connections:

Caused by: javax.xml.ws.WebServiceException: Failed to access the WSDL at: https://myserver.mydomain.lu/services/myservice/MyService1?WSDL. It failed with:
java.security.cert.CertificateException: No subject alternative DNS name matching myserver.mydomain.lu found..
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(RuntimeWSDLParser.java:162)
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:144)
at com.sun.xml.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:265)
at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:228)
at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:176)
at com.sun.xml.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:104)
at javax.xml.ws.Service.<init>(Service.java:56)
… 16 more
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative DNS name matching myserver.mydomain.lu found.
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1699)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1172)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
at java.net.URL.openStream(URL.java:1010)
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.createReader(RuntimeWSDLParser.java:804)
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.resolveWSDL(RuntimeWSDLParser.java:262)
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:129)
… 22 more
Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching myserver.mydomain.lu found.
at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:193)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:77)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:264)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:250)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185)
… 37 more

The above error/problem could be fixed by disabling HTTPS checks using the approach presented in the web site https://nakov.com/blog/2009/07/16/disable-certificate-validation-in-java-ssl-connections/

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

// ….
static {
disableSslVerification();
}

// ….
private static void disableSslVerification() {
try
{
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws CertificateException {
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws CertificateException {
}
}
};
<pre><code>        // Install the all-trusting trust manager
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    }
}



Best regards,

Huseyin OZVEREN