All of My Records

[Error] HTTPS 통신 시 SSLHandshakeException PKIX 에러 :: sun.security.validator.ValidatorException: PKIX path building failed

by 캐떠린

❓ Problem: 서버에서 HTTPS 통신 시 SSLHandshakeException: PKIX 오류가 발생하여 통신 불가

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

 

발생 이력

일전에 전달받은 URL로 요청을 보내려고 하는데, 회사 개발 서버에서 Java를 통해 통신 시, 위와 같은 오류가 발생하여 당시 대안으로 웹에서 js fetch를 사용하여 정상적으로 통신했었다. 그땐 상대방 문제인줄 알고 넘어갔었는데 다시 한번 개발 서버에서 HTTPS 통신 시 동일한 문제를 만나게 되었다.

 

나는 당시 회사 개발 서버와 클라우드 환경에서 개발을 진행하였는데, 개발 서버에서 PKIX 오류가 나는 것이 이상하게 클라우드 환경에서 진행할 때는 통신에 문제가 없었다. 그게 의아했었고 나는 그게 다른 이유 때문인 줄 알았으나.. 찐 이유는 다른 곳에 있었다. (원인 분석 파트에서 계속..)


내가 검색만 하면 나오는 이 오류를 금방 해결 못했던 가장 큰 이유. 내가 멍청했던것도 크지만 요청을 보내는 내가 수정할 수 있는 오류인지 혹은 요청을 받는 상대가 수정할 수 있는 오류인지, 즉 누가 해결의 주체가 되느냐였다.

➡️ 정답은 요청을 보내는 내가 해결의 주체 입니다.

 

⚠️ 원인 분석

답은 역시나 오류메시지 안에 있다.

unable to find valid certification path to requested target (요청한 대상의 유효한 인증 경로를 찾을 수 없습니다.)

 

그렇다면 왜 요청한 대상(상대방)의 유효한 인증 경로를 찾을 수 없다는 에러가 발생했을까?

여러 글들에서 배운 짧은 지식을 정리하고 공부하기위애 적어보자면 아래와 같다.

 

먼저, HTTPS 통신에서 사용되는 SSL HandShake 방식은 아래와 같다.

1. 서버 → 클라이언트에게 SSL 인증서를 전달

2. 클라이언트가 루트CA 인증서를 통해 서버가 보낸 SSL 인증서가 신뢰 가능한지 확인

3. 보안 연결 수립

 

나의 경우 2번에서 문제가 발생했다.

Java는 루트 인증 저장소(cacerts)에 있는 루트 CA 인증서 목록을 통해 SSL 인증서의 신뢰성을 검증한다.

서버로 부터 전달받은 SSL 인증서가 루트 인증 저장소의 인증서 목록에 존재한다면 신뢰, 없다면  신뢰하지 못한다.

 

추가적으로 Java 버전별로 cacerts에 포함된 루트 CA 인증서 목록이 상이하다. 버전을 업그레이드 할 때 새로운 루트 CA가 추가되기도 하고, 보안 문제로 인해 기존 루트 CA가 제거되기도 한다.

➡️ 위와 같은 이유로 내가 회사 개발서버(Java8)에서 통신할 때는 PKIX 오류가 발생했고, 클라우드 환경(Java11)에서 통신할 때는 오류가 발생하지 않았던 것.. (해당 인증서가 JDK11에는 신뢰하는 인증서 목록에 있었나보다.)

 

 

❗ Solution

해결 방법은

1. 자바 버전 업그레이드

2. 내가 직접 해당 인증서를 루트 CA 목록에 추가해주기

 

1번 회사 개발서버의 자바 버전을 이것때문에 업그레이드 하는 것은 당연히 현실적으로 불가능하고

2번 방법을 사용하면 된다.

 

1. 루트 CA 목록에 추가할 인증서를 추출하는 작업

(1) 내가 요청보낼 url에 접속 → 상단 주소창 옆 아이콘 클릭 → '이 연결은 안전합니다.' 클릭

 

(2) '인증서가 유효함' 클릭

 

(3) 팝업창에서 '세부정보' 탭 클릭 → 우측 하단 '내보내기' 클릭하여 인증서 다운로드

 

2. cacerts의 루트 CA 인증서 목록에 다운로드 받은 인증서 추가해주기

먼저 cacerts의 경로는 아래와 같다.

파워쉘을 실행하여 아래 명령어를 입력 후 (암호는 아래 명령어에서 인증서 등록 시 changeint으로 설정) → y 입력

keytool.exe -import -alias {별칭} -keystore "{Java 경로}\lib\security\cacerts" -storepass changeit -file "{인증서 파일 경로}"
keytool.exe -import -alias test-ca -keystore "C:\Program Files\Java\jdk-11\lib\security\cacerts" -storepass changeit -file "C:\code\devTest\test.crt"

 

위와 같이 루트 인증서를 추가하고 확인해보면 적용 완료!

cacerts파일의 경로로 이동해보면 해당 파일이 수정된 날짜가 바뀌어 있음을 확인 할 수 있다!

 

내가 회사에서 사용하는 개발 도구는 WAS 기반이라 톰캣을 재기동하여 요청을 보내본 결과 정상 전송되는 것을 확인하였다 ^~^

 

그동안 나를 괴롭혔던 PKIX 요놈 잡았다..

 

 

* 글 작성 및 오류 해결에 참고한 포스트: https://colabear754.tistory.com/87, https://devtalk.kakao.com/t/pkix-path-building-failed/123115, https://psip31.tistory.com/90

블로그의 프로필 사진

블로그의 정보

All of My Records

캐떠린

활동하기