The initial program is quite simple:
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.SSLSocket;
public class JVT
{
public static void main(final String[] args) throws Throwable
{
SSLSocketFactory sslSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket)sslSocketFactory.createSocket("localhost", 12345);
sslsocket.getOutputStream().write("Hello from the world of Java\n".getBytes());
}
}
But when I connected I got:
Exception in thread "main" javax.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
Oh, what a readable exception... So it appears it doesn't like the certificate of my Python end and I should probably supply that to Java somehow. keytool is the tool for the job (a very cheap and nasty tool). I tried doing a:
$ keytool -import cert
Which did seem to import it (shows with
keytool -list
) but still the exception.Tried some debugging:
-Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol -Djavax.net.debug=ssl
It showed the standard signing authority certificates but not my one...
And that's when I give up and copy someone else's solution to the problem. This is how to replace the certificate checking with a null implementation:
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
public class JVT
{
public static void main(final String[] args) throws Throwable
{
// Create empty HostnameVerifier
HostnameVerifier hv = new HostnameVerifier()
{
public boolean verify(String urlHostName, SSLSession session)
{
System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
return true;
}
};
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]
{
new X509TrustManager()
{
public java.security.cert.X509Certificate[] getAcceptedIssuers()
{
return null;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
{
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
{
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
SSLSocketFactory sslSocketFactory = sc.getSocketFactory();
SSLSocket sslsocket = (SSLSocket)sslSocketFactory.createSocket("localhost", 12345);
sslsocket.getOutputStream().write("Hello from the world of Java\n".getBytes());
}
}
So now it works (for transport) but I must find out how to do the certificates properly.
No comments:
Post a Comment