I got host name wrong exception.I have used this code(got it from some link) in my program.My program is working fine.My question is it secure enough?? (as it is not validating certificate chains)
public class Host {
public String subscribe() throws Exception {
String resp = "";
String urlString="https://xxx.xxx.xx.xx:8443/WebApplication3/NewServlet";
URL url;
URLConnection urlConn;
DataOutputStream printout;
DataInputStream input;
String str = "";
int flag=1;
try {
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName + " vs. "
+ session.getPeerHost());
return true;
}
};
trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(hv);
url = new URL(urlString);
urlConn = url.openConnection();
urlConn.setDoInput(true);
Object object;
urlConn.setUseCaches(false);
urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
input = new DataInputStream(urlConn.getInputStream());
while (null != ((str = input.readLine()))) {
if (str.length() >0) {
str = str.trim();
if(!str.equals("")) {
//System.out.println(str);
resp += str;
}
}
}
input.close();
} catch ( MalformedURLException mue) {
mue.printStackTrace();
} catch(IOException ioe) {
ioe.printStackTrace();
}
return resp;
}
public static class miTM implements javax.net.ssl.TrustManager,
javax.net.ssl.X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException {
return;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException {
return;
}
}
private static void trustAllHttpsCertificates() throws Exception {
// Create a trust manager that does not validate certificate chains:
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new miTM();
trustAllCerts[0] = tm;
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, null);
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
}
The code in miTM
actually disables any SSL security checks, so the security level is pretty low (you will only get errors if the SSL certificate is broken but you don't get errors when the certificate doesn't match the domain).
Basically, you try to make a connection without any security at all. If that's what you want, the solution might be "secure enough" but most likely, the answer is "no."
The correct solution for this kind of problem is to create a matching certificate for this domain.
Unfortunately, this isn't possible when your HTTP server is using "virtual hosting" (= many domain names map to the same IP address). The correct solution for this problem is to get your own IP address.
If you still want to try a Java-only solution, have a look at this answer: https://stackoverflow.com/a/3293720/34088
Here is a way to clean up your code and to remain secure. I suppose the code connects to a known service (trusted). To make Java SSL stack accept connection even with hostname mismatch, the best way is to add the server certificate to the JVM trust store.
First you can export the server certificate from your browser and save it on disk. From Linux, you can use openssl s_client -connect xxx.xxx.xx.xx:8443
and copy/paster the server certificate in ascii-armored format to a text file.
Then import the server certificate into jre/lib/security/cacerts
JKS file with keytool
keytool -import -alias myservice -file servercertificate.cer
Another option I prefer, to avoid regression when Java is updated, is to copy cacerts
in your own place and declares it thanks to the javax.net.ssl.trustStore
system property.
As the server certificate is in the trust store... it is trusted, until it expires. This is often used for self-signed server certificates.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With