개발관련/오류노트

javax.net.ssl.SSLHandshakeException 해결 : sun.security.validator.ValidatorException : PKIX path building failed Error

Rateye 2021. 12. 6. 09:59
728x90
반응형
질문 : 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
728x90
반응형