질문 : javax.net.ssl.SSLHandshakeException 해결 : sun.security.validator.ValidatorException : PKIX 경로 빌드 실패 오류?
편집 :- 질문의 형식을 지정하고 내 블로그 에서보다 표현 가능한 방식으로 답변을 수락했습니다.
다음은 원래 문제입니다.
이 오류가 발생합니다.
자세한 메시지 sun.security.validator.ValidatorException : PKIX 경로 구축 실패 :
sun.security.provider.certpath.SunCertPathBuilderException : 요청 된 대상에 대한 유효한 인증 경로를 찾을 수 없습니다.
원인 javax.net.ssl.SSLHandshakeException : sun.security.validator.ValidatorException : PKIX 경로 구축 실패 : sun.security.provider.certpath.SunCertPathBuilderException : 요청 된 대상에 대한 유효한 인증 경로를 찾을 수 없습니다.
Tomcat 6을 웹 서버로 사용하고 있습니다. 서로 다른 포트의 서로 다른 Tomcat에 두 개의 HTTPS 웹 응용 프로그램이 설치되어 있지만 동일한 컴퓨터에 있습니다. App1(port 8443)
및 App2(port 443)
라고 말합니다. App1
연결 App2
. 때 App1
연결 App2
I 위의 오류가 발생합니다. 나는 이것이 매우 일반적인 오류라는 것을 알고 있으므로 다른 포럼과 사이트에서 많은 솔루션을 발견했습니다. 두 Tomcat의 server.xml
에 아래 항목이 있습니다.
keystoreFile="c:/.keystore"
keystorePass="changeit"
모든 사이트는 app2에서 제공 한 인증서가 app1 jvm의 신뢰할 수있는 저장소에없는 것과 동일한 이유를 말합니다. IE 브라우저에서 동일한 URL을 입력하려고했을 때도 마찬가지인 것 같습니다. 작동합니다 (워밍과 함께이 웹 사이트의 보안 인증서에 문제가 있습니다. 여기에서이 웹 사이트를 계속합니다). 그러나 동일한 URL이 Java 클라이언트 (제 경우)에 의해 공격되면 위의 오류가 발생합니다. 그래서 그것을 신뢰 저장소에 넣기 위해 다음 세 가지 옵션을 시도했습니다.
옵션 1
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
Option2 환경 변수에서 아래 설정
CATALINA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value
Option3 환경 변수에서 아래 설정
JAVA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value
그러나 아무것도 작동하지 않았습니다 .
마지막으로 작동 한 것은 Apache HttpClient로 유효하지 않은 SSL 인증서를 처리하는 방법에 제안 된 Java 접근 방식을 실행하는 것입니다. Pascal Thivent에 의해 즉 InstallCert 프로그램을 실행합니다.
하지만이 접근 방식은 devbox 설정에는 좋지만 프로덕션 환경에서는 사용할 수 없습니다.
app2
server.xml
에서 동일한 값과 신뢰 저장소에서 동일한 값을 설정하여 언급했을 때 위에서 언급 한 세 가지 접근 방식이 작동하지 않는 이유가 궁금합니다.
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore") and System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
app1
프로그램에서.
자세한 내용은 연결 방법입니다.
URL url = new URL(urlStr);
URLConnection conn = url.openConnection();
if (conn instanceof HttpsURLConnection) {
HttpsURLConnection conn1 = (HttpsURLConnection) url.openConnection();
conn1.setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
reply.load(conn1.getInputStream());
답변
%JAVA_HOME%\lib\security\cacerts
에있는 사용 된 JVM의 신뢰 저장소 파일에 App2 에 대한 인증서를 추가해야합니다.
먼저 다음 명령을 실행하여 인증서가 이미 신뢰 저장소에 있는지 확인할 수 있습니다. keytool -list -keystore "%JAVA_HOME%/jre/lib/security/cacerts"
(비밀번호를 제공 할 필요 없음)
인증서가 누락 된 경우 브라우저로 다운로드하여 가져오고 다음 명령을 사용하여 신뢰 저장소에 추가 할 수 있습니다.
keytool -import -noprompt -trustcacerts -alias <AliasName> -file <certificate> -keystore <KeystoreFile> -storepass <Password>
예:
keytool -import -noprompt -trustcacerts -alias myFancyAlias -file /path/to/my/cert/myCert.cer -keystore /path/to/my/jdk/jre/lib/security/cacerts/keystore.jks -storepass changeit
가져온 후 첫 번째 명령을 다시 실행하여 인증서가 추가되었는지 확인할 수 있습니다.
Sun / Oracle 정보는 여기 에서 찾을 수 있습니다.
출처 : https://stackoverflow.com/questions/9619030/resolving-javax-net-ssl-sslhandshakeexception-sun-security-validator-validatore