Certificate Acceptance in Java

I am having problems interacting with an HTTPS site through Java. My program uses one URL with an untrusted certificate every time the program starts. This program should work on several systems. I currently have the following:

public class A{ HostnameVerifier hv = new HostnameVerifier(){ public boolean verify(String urlHostName, SSLSession session){ return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(hv); 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 = null; try { sc = javax.net.ssl.SSLContext.getInstance("SSL"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } try { sc.init(null, trustAllCerts, null); } catch (KeyManagementException e) { e.printStackTrace(); } javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } 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; } } 

With this code, I can do the following simply:

 URL url = new URL(urlString); URLConnection cnx = url.openConnection(); cnx.connect(); InputStream ins = cnx.getInputStream(); BufferedReader in = new BufferedReader(new InputStreamReader(ins)); String curline; while( (curline = in.readLine()) != null ) { System.out.println(curline); } 

However, I cannot do the following:

 httpClient = new HttpClient(); PostMethod postMethod = null; int intResult = 0; postMethod = new PostMethod(authURL); Enumeration emParams = authParams.propertyNames(); while (emParams.hasMoreElements()) { String paramName = (String) emParams.nextElement(); String paramValue = authParams.getProperty(paramName); postMethod.addParameter(paramName, paramValue); } intResult = httpClient.executeMethod(postMethod); postMethod.releaseConnection(); ins.close(); 

When executeMethod (postMethod) is executed, I get an SSLHandshakeException, CertPathBuilderException, etc.

What can I do to fix this? I am thinking about accepting a certificate or just bypassing the entire certificate verification (since the program runs inside a private network).

thanks

+5
source share
2 answers

It looks like you are using Apache HttpClient 3. If this is really version 3, you need to create your own SecureProtocolSocketFactory as described in the Apache HttpClient 3 SSL guide . Here is an example .

For Apache HttpClient 4, you must pass the SSLContext constructor in the (HttpClient) SSLSocketFactory , as described in the answers to this question (including notes regarding hostname validation).

However, generally speaking, this approach does not follow. You will actually disable the SSL / TLS connection authentication part by doing this, making it vulnerable to MITM attacks.

You should explicitly import the server certificate into the client trust store instead, as described in this answer .

I think either accept the certificate, or just bypass all certificate verification (since the program runs inside the private network).

What you are saying is that you are ready to use SSL / TLS for encryption only on your private network, because you do not trust your users not to look at the traffic that their computers can bypass, but you are also supposed to these users will not be able to carry out a MITM attack. This is not entirely clear. If you trust them enough, you can also send data in a clear one. If you do not, you must correctly implement SSL / TLS, including authentication steps (certificate verification and name verification host).

+5
source

HttpClient 4.3:

  HttpClientBuilder cb = HttpClientBuilder.create(); SSLContextBuilder sslcb = new SSLContextBuilder(); sslcb.loadTrustMaterial(KeyStore.getInstance(KeyStore.getDefaultType()), new TrustSelfSignedStrategy()); cb.setSslcontext(sslcb.build()); CloseableHttpClient httpclient = cb.build(); 
+1
source

All Articles