Many time there might be a situation on PROD where a big application and one of the call is failing with SSL Handshake error . It is very difficult to get the approvals and enable debug mode in PROD environments . To test your truststore for Interface connectivity we can just use a sample standalone jAVA program . if it fails then we can conclude what might have missed in the trus store .At the same time we can test by importing interface certs also .
ERROR : javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
testSSL.java
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;
/** Establish a SSL connection to a host and port, writes a byte and
*/
public class testSSL {
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("Usage: "+testSSL.class.getName()+" <host> <port>");
System.exit(1);
}
try {
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(args[0], Integer.parseInt(args[1]));
SSLParameters sslparams = new SSLParameters();
sslparams.setEndpointIdentificationAlgorithm("HTTPS");
sslsocket.setSSLParameters(sslparams);
InputStream in = sslsocket.getInputStream();
OutputStream out = sslsocket.getOutputStream();
// Write a test byte to get a reaction :)
out.write(1);
while (in.available() > 0) {
System.out.print(in.read());
}
System.out.println("Successfully connected");
} catch (Exception exception) {
exception.printStackTrace();
System.exit(1);
}
}
}
- Copy code to somewhere
- Call Java compiler
/usr/java/jdk1.6.0_45/bin/javac /tmp/testSSL.java
(use your version of Java here) - Call tool with ClassPath (-cp) that you copied the file to:
/usr/java/jdk1.6.0_45/bin/java -cp /tmp testSSL my-url.com 443
Usage:
extract certs from server:openssl s_client -connect server:443
-showcerts
negative test cert / keytool:java testSSL server 443
you should get something likejavax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
import cert into default keytool:keytool -import -alias alias.server.com -keystore $JAVA_HOME/jre/lib/security/cacerts
positive test cert / keytool:java testSSL server 443
you should get this:Successfully connected
You can use Custom trust store in the below way
# import certificate into your local TrustStore keytool -import -trustcacerts -storepass changeit -file "./class 1 root ca.cer" -alias C1_ROOT_CA -keystore ./LocalTrustStore # use it in JAVA: java -Djavax.net.ssl.trustStore=./LocalTrustStore -jar testSSL $HOST $PORT
Use -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 to specify specific protocol which you want to test if you have any specific reason .
run with keystore
C:\IBM\WebSphere\AppServer\java\8.0\jre\bin\java -Djavax.net.ssl.trustStore=C:\IBM\WebSphere\AppServer\profiles\MyAppSrv01\config\cells\MyNode01Cell\nodes\MyNode01\trust.p12 -Djavax.net.ssl.trustStorePassword=mypass123 -Djavax.net.ssl.trustStoreType=pkcs12 -cp C:\tools\JavaSSL testSSL myserver.com 636
Above java code isn’t validating the hostname. Use below added with SSLParamters for Hostname validation as well .
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;
public class testSSL {
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("Usage: "+testSSL.class.getName()+" <host> <port>");
System.exit(1);
}
try {
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(args[0], Integer.parseInt(args[1]));
SSLParameters sslparams = new SSLParameters();
sslparams.setEndpointIdentificationAlgorithm("HTTPS");
sslsocket.setSSLParameters(sslparams);
InputStream in = sslsocket.getInputStream();
OutputStream out = sslsocket.getOutputStream();
// Write a test byte to get a reaction :)
out.write(1);
while (in.available() > 0) {
System.out.print(in.read());
}
System.out.println("Successfully connected");
} catch (Exception exception) {
exception.printStackTrace();
}
}
}