2011-02-17 3 views
2

Java 프로그램에서 HttpsURLConnection을 사용하고 https://로 시작하는 URL을 열려고하면 다음과 같은 오류 메시지가 나타납니다.클라이언트 프로그램이 Java로되어 있고 C#으로되어 있지 않을 때 서버 SSL 인증서를 추가해야하는 이유는 무엇입니까?

요청한 대상에 대한 유효한 인증 경로를 찾을 수 없음

및 솔루션 나는 to add the server certificate to the client certificate storage을 발견했다. 그러나 HttpWebRequest를 사용하는 C# 프로그램을 작성하면 어디에도 아무 것도 추가 할 필요가 없습니다.

그래서 나를 위해 그것은 C# 클라이언트처럼 "그냥 작동"및 Java 클라이언트는 망치로 조정할 후 작동합니다.

Java 클라이언트에 추가 단계가 필요한 이유는 무엇입니까? 어떻게해도 인증서를 JVM의 클라이언트 저장소에 저장하지 않아도됩니까?

답변

2

HttpWebRequest는 인증서의 유효성을 검사하기 위해 Window 자체 인증서 저장소를 사용합니다 (IE와 동일). Internet Explorer에서 인증서 또는 CA 경로를 신뢰할 수있는 루트로 되돌려 서 인증서를 올바르게 확인할 수 있으면 HttpWebRequest가 인증서를 승인해야합니다.

Java 케이스에서 서버 인증서 자체를 추가하는 것이 잘못된 것으로 의심되는 경우 자체 서명하지 않으면 선택의 여지가 없습니다. 대신 CA 경로를 신뢰할 수있는 루트에 다시 추가해야합니다. 필요할 경우이 인증서를 Windows의 CA 저장소에서 꺼내거나 루트 CA의 웹 사이트에서 다운로드 할 수 있습니다.

2

저는 C#이 MSIE와 동일한 HTTP 클라이언트를 사용하기 때문에 MSIE와 같은 미리 설치된 SSL 인증서가 많기 때문에 믿습니다. JVM은 사전 설치된 인증서가 적습니다.

1

기본적으로 Java는 자체 트러스트 스토어 세트를 사용합니다 (기본 트러스트 스토어에서는 JSSE Reference Guide 참조).

Windows 인증서 저장소를 사용하려는 경우 Windows-ROOT keystore을 트러스트 스토어로 사용할 수 있습니다.

1

이 주제에 대한 유용한 정보는 오라클 사이트의 Leveraging Security in the Native Platform Using Java SE 6 TechnologyJava Secure Socket Extension (JSSE) Reference Guide입니다.

당신은 자바가 다음 실행에 다음과 같은 시스템 속성을 지정할 수 있습니다 인증서의 유효성을 검사하기 위해 Windows 인증서 저장소를 사용하려면 :

는 Windows 인증서 저장소를 사용하는 하나의 연결을 원하는 경우 -Djavax.net.ssl.keyStoreType=Windows-MY -Djavax.net.ssl.trustStoreType=Windows-ROOT

인증서를 확인하려면 필요에 맞게 다음 코드를 수정할 수 있습니다.

KeyStore ks = KeyStore.getInstance("Windows-MY"); 
    ks.load(null, null); 

    KeyStore ts = KeyStore.getInstance("Windows-ROOT"); 
    ts.load(null, null); 

    TrustManagerFactory tmf = TrustManagerFactory 
       .getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
    tmf.init(ts); 

    KeyManagerFactory kmf = KeyManagerFactory 
       .getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
    kmf.init(ks, new char[0]); 

    SSLContext ctx = SSLContext.getInstance("TLS"); 
    ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);  

    URL url = new URL("https://some.web.site.org"); 
    javax.net.ssl.HttpsURLConnection urlConnection = 
      (javax.net.ssl.HttpsURLConnection) url.openConnection(); 
    urlConnection.setSSLSocketFactory(ctx.getSocketFactory()); 
    urlConnection.connect(); 
    try (InputStream in = urlConnection.getInputStream();) { 
     byte[] chunk = new byte[1024]; 
     for (int len; (len = in.read(chunk)) > -1;) { 
      System.out.write(chunk, 0, len); 
     } 
    } finally { 
     urlConnection.disconnect(); 
    } 
관련 문제