Peer未在java中进行身份validation

我已经去了几乎所有与此例外相关的post。 实际上我的问题是我有一个java应用程序,通过它我点击一个URL并从中得到响应。

命中URL的代码是:

HttpGet getRequest = new HttpGet("https://urlto.esb.com"); HttpResponse httpResponse = null; DefaultHttpClient httpClient = new DefaultHttpClient(); httpResponse = httpClient.execute(getRequest); 

这里我得到javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

因此,经过一些谷歌搜索后,我才知道我可以在运行应用程序的java密钥库中导入证书。 所以我在密钥库中导入了证书,这段代码正常运行。 但我不想要这个解决方案,所以经过一些搜索后我才知道我可以使用TrustManager来做同样的事情,而无需将证书导入密钥库。 所以我编写了如下代码:

 @Test public void withTrustManeger() throws Exception { DefaultHttpClient httpclient = buildhttpClient(); HttpGet httpGet = new HttpGet("https://urlto.esb.com"); HttpResponse response = httpclient.execute( httpGet ); HttpEntity httpEntity = response.getEntity(); InputStream inputStream = httpEntity.getContent(); BufferedReader reader = new BufferedReader(new InputStreamReader( inputStream)); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } inputStream.close(); String jsonText = sb.toString(); System.out.println(jsonText); } private DefaultHttpClient buildhttpClient() throws Exception { DefaultHttpClient httpclient = new DefaultHttpClient(); SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, getTrustingManager(), new java.security.SecureRandom()); SSLSocketFactory socketFactory = new SSLSocketFactory(sc); Scheme sch = new Scheme("https", 443, socketFactory); httpclient.getConnectionManager().getSchemeRegistry().register(sch); return httpclient; } private TrustManager[] getTrustingManager() { TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } @Override public void checkClientTrusted(X509Certificate[] certs, String authType) { // Do nothing } @Override public void checkServerTrusted(X509Certificate[] certs, String authType) { // Do nothing } } }; return trustAllCerts; } 

这段代码也有效,但我的问题是我没有检查与证书相关的任何内容,以及如何连接信任。 调试后我才知道只有checkServerTrusted正在点击。 所以我在checkServerTrusted写了一些checkServerTrusted来validation证书中的certs以及我的应用程序中的certs ,例如.cer或.crt文件。

每一个帮助将不胜感激。

在@EpicPandaForce之后更新(使用Apache HttpClient 4.3)

  try { keyStore = KeyStore.getInstance("JKS"); InputStream inputStream = new FileInputStream("E:\\Desktop\\esbcert\\keystore.jks"); keyStore.load(inputStream, "key".toCharArray()); SSLContextBuilder sslContextBuilder = SSLContexts.custom().loadTrustMaterial(keyStore, new TrustSelfSignedStrategy()); sslcontext = sslContextBuilder.build(); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext); HttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); HttpGet httpGet = new HttpGet("https://url.esb.com"); HttpResponse response = httpclient.execute( httpGet ); HttpEntity httpEntity = response.getEntity(); InputStream httpStram = httpEntity.getContent(); BufferedReader reader = new BufferedReader(new InputStreamReader( httpStram)); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } httpStram.close(); inputStream.close(); String jsonText = sb.toString(); System.out.println(jsonText); } catch(Exception e) { System.out.println("Loading keystore failed."); e.printStackTrace(); } 

从技术上讲,当您使用Apache HttpClient 4.x时,更简单的解决方案如下:

  SSLContext sslcontext = null; try { SSLContextBuilder sslContextBuilder = SSLContexts.custom() .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()); sslcontext = sslContextBuilder.build(); 

其中trustStore是这样初始化的

  KeyStore keyStore = null; try { keyStore = KeyStore.getInstance("BKS", BouncyCastleProvider.PROVIDER_NAME); //you can use JKS if that is what you have InputStream inputStream = new File("pathtoyourkeystore"); try { keyStore.load(inputStream, "password".toCharArray()); } finally { inputStream.close(); } } catch(Exception e) { System.out.println("Loading keystore failed."); e.printStackTrace(); } return keyStore; } 

然后创建HttpClient

 SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext); httpclient = HttpClients .custom() .setSSLSocketFactory(sslsf).build(); 

编辑:我的确切代码是这样的:

  SSLContextBuilder sslContextBuilder = SSLContexts.custom() .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()); sslcontext = sslContextBuilder.build(); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext, new String[] {"TLSv1"}, null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER ); httpclient = HttpClients .custom() .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) .setSSLSocketFactory(sslsf).build();