Created
June 21, 2019 16:57
-
-
Save skanga/d679e7e0f082e26e156494330c66b5b8 to your computer and use it in GitHub Desktop.
Make SSL connections using HttpsURLConnection when certificates cannot be validated (self-signed certs) and/or the hostname cannot be validated (ssh tunnels, etc)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.io.InputStreamReader; | |
import java.io.Reader; | |
import java.net.URL; | |
import java.security.KeyManagementException; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.cert.X509Certificate; | |
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; | |
// VERY BAD. Never use in production | |
public class InsecureSSL | |
{ | |
// Create a trust manager that does NOT validate certificate chains | |
private static TrustManager[] trustAllCerts = new TrustManager[] { | |
new X509TrustManager() | |
{ | |
public X509Certificate[] getAcceptedIssuers() | |
{ | |
return null; | |
} | |
public void checkClientTrusted(X509Certificate[] certs, String authType) | |
{ | |
} | |
public void checkServerTrusted(X509Certificate[] certs, String authType) | |
{ | |
} | |
} | |
}; | |
// A hostname verifier for which ALL hosts valid | |
private static HostnameVerifier allHostsValid = new HostnameVerifier() | |
{ | |
public boolean verify(String hostname, SSLSession session) | |
{ | |
return true; | |
} | |
}; | |
// A hostname verifier for which only localhost and 127.0.0.1 valid | |
public static HostnameVerifier localhostValid = new HostnameVerifier() | |
{ | |
public boolean verify(String hostname, SSLSession session) | |
{ | |
return "localhost".equals(hostname) || "127.0.0.1".equals(hostname); | |
} | |
}; | |
private static SSLContext getInstance() throws KeyManagementException, NoSuchAlgorithmException | |
{ | |
return getInstance("TLS"); | |
} | |
//get a 'Relaxed' SSLContext with no trust store (all certificates are valid) | |
private static SSLContext getInstance(String protocol) throws KeyManagementException, NoSuchAlgorithmException | |
{ | |
SSLContext sc = SSLContext.getInstance(protocol); | |
sc.init(null, trustAllCerts, new java.security.SecureRandom()); | |
return sc; | |
} | |
private static HttpsURLConnection testNormal() throws IOException | |
{ | |
URL url = new URL("https://www.google.com/"); | |
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); | |
conn.connect(); | |
return conn; | |
} | |
// The actual hostname and one on cert differ | |
private static HttpsURLConnection testBadName() throws IOException | |
{ | |
URL url = new URL("https://172.217.5.100/"); | |
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); | |
conn.setHostnameVerifier(InsecureSSL.allHostsValid); | |
conn.connect(); | |
return conn; | |
} | |
// Cert chain not in default truststore | |
private static HttpsURLConnection testMissingCert() throws IOException, NoSuchAlgorithmException, KeyManagementException | |
{ | |
URL url = new URL("https://www.aragon.es"); | |
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); | |
conn.setSSLSocketFactory(InsecureSSL.getInstance().getSocketFactory()); | |
conn.connect(); | |
return conn; | |
} | |
private static void getConnData(HttpsURLConnection conn) throws IOException | |
{ | |
Reader reader = new InputStreamReader(conn.getInputStream()); | |
while(true) | |
{ | |
int ch = reader.read(); | |
if(ch == -1) | |
{ | |
break; | |
} | |
System.out.print((char) ch); | |
} | |
System.out.println("\n\n"); | |
conn.disconnect(); | |
} | |
public static void main(String... args) throws Exception | |
{ | |
boolean verbose = false; | |
if (args.length > 0 && args[0].equalsIgnoreCase("-v")) | |
verbose = true; | |
HttpsURLConnection conn1 = testNormal(); | |
System.out.println("Normal status: " + conn1.getResponseCode()); | |
if(verbose) getConnData(conn1); | |
HttpsURLConnection conn2 = testBadName(); | |
System.out.println("Bad Name status: " + conn2.getResponseCode()); | |
if(verbose) getConnData(conn2); | |
HttpsURLConnection conn3 = testMissingCert(); | |
System.out.println("Missing Cert status: " + conn3.getResponseCode()); | |
if(verbose) getConnData(conn3); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment