接受Java中的证书

我在通过Java与HTTPS站点交互时遇到问题。 每次程序运行时,我的程序都会使用一个带有不受信任证书的URL。 该程序必须在多个系统上运行。 目前,我有以下内容:

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; } } 

使用此代码,我可以执行以下操作:

 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); } 

但是,我无法做到以下几点:

 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(); 

当执行executeMethod(postMethod)时,我得到一个SSLHandshakeException,CertPathBuilderException等。

我该怎么做才能解决这个问题? 我正在考虑接受证书或绕过所有证书validation(因为程序在专用网络内部运行)。

谢谢

看起来你正在使用Apache HttpClient 3.如果这确实是版本3,你需要构建自己的SecureProtocolSocketFactory如Apache HttpClient 3 SSL指南中所述 。 这里有一个例子 。

对于Apache HttpClient 4,您应该能够将SSLContext传递给(HttpClient) SSLSocketFactory的构造函数,如本问题的答案中所述 (包括有关主机名validation的注释)。

但是,一般来说,不要遵循这种方法。 您可以通过这样做完全禁用SSL / TLS连接的身份validation部分,从而使其容易受到MITM攻击。

您应该在客户端的信任存储中明确导入服务器证书,如本答案中所述 。

我正在考虑接受证书或绕过所有证书validation(因为程序在专用网络内部运行)。

你所说的是你只愿意在你的私人网络中使用SSL / TLS进行加密,因为你不相信它的用户不会看到他们机器周围的流量,但你也是假设这些用户将无法执行MITM攻击。 这没有多大意义。 如果您足够信任它们,您也可以清楚地发送数据。 如果不这样做,那么您应该正确实施SSL / TLS,包括身份validation步骤(证书和主机名validation)。

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();