2015-01-28 2 views
0

이 예외와 관련된 거의 모든 게시물을 보았습니다. 사실 내 문제는 내가 URL을 치고 그것을 통해 응답을 받고있는 Java 응용 프로그램입니다. URL을 칠피어가 Java에서 인증되지 않았습니다.

코드입니다 : 내가

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated을 얻고있다

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

그래서 일부 Google 검색 후 나는 응용 프로그램이 실행되는 자바의 키 저장소에 인증서를 가져올 수 있다는 것을 알게. 그래서 키 저장소에 인증서를 가져 왔고이 코드가 작동 중입니다. 하지만이 솔루션을 원하지 않으므로 검색을 한 번 더 수행하면 키 저장소에 인증서를 가져 오지 않고 동일한 작업에 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이 타격 중임을 알게되었습니다. 그래서 certs에 들어있는 인증서와 일부 .cer 또는 .crt 파일과 같은 내 응용 프로그램에있는 인증서의 유효성을 검사하기 위해 checkServerTrusted에 무엇인가를 적어 놓았습니다.

모든 도움을 주실 수 있습니다.

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

장소 :

업데이트 @EpicPandaForce 후 아파치 HttpClient를 4.x의를 사용하는 것처럼보고,

 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(); 
     } 
+0

당신이 본 http://stackoverflow.com/questions/8693991/java-ignore-expired-ssl-sertificate/8694377 # 8694377? – EpicPandaForce

+0

@EpicPandaForce, 예, 인증서를 확인할 수있는 방법은 무엇입니까? 내가 가진 것과 서버에서 나온 것을 의미합니다. – Amogh

답변

1

기술적으로 (아파치 HttpClient를 4.3을 사용하여), 간단한 해결책은 다음이 될 것입니다 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(); 
+0

오, 이것으로 내가 @ 키 스토어를로드 할 수 있습니다. – Amogh

+0

예! 그러나 이렇게하면 키 스토어에서 제공 한 인증서 만 신뢰하게됩니다. 앱에 인증서가있는 경우 해당 인증서를로드 할 수 있어야합니다. – EpicPandaForce

+0

그게 내가 원하는거야. 그래서 만약 내가'cacerts' 파일을 내 개발 PC에 가져 오면 병을 만드는 동안 내 앱에이 cacerts를 복사하고 요청을하는 동안 응답 – Amogh

관련 문제