
시작은 예외 메시지 한 줄
Java로 만든 프로그램을 실행했을 때, 아래와 같은 예외가 발생했습니다.
특히 외부 HTTPS 서버에 접속하려 할 때 터졌습니다.
javax.net.ssl.SSLHandshakeException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
🧠 이 예외의 의미는?
📌 한마디로 말하면:
"Java가 접속하려는 서버의 인증서를 신뢰하지 못했다"는 뜻입니다.
조금 더 자세히 보면:
1️⃣ | Java 앱이 https://example.com 같은 서버에 SSL 연결 시도 |
2️⃣ | 서버는 자신의 SSL 인증서를 보냄 |
3️⃣ | Java는 이 인증서가 자신이 신뢰하는 기관에서 발급됐는지 확인 |
4️⃣ | 인증서의 발급 경로(체인)가 신뢰할 수 없다면 → SSLHandshakeException 발생 |
이때 "PKIX path building failed"란 말은,
신뢰할 수 있는 루트 인증서까지 연결되는 경로(path)를 못 찾았다는 뜻입니다.
🔍 내 환경에서는 왜 생겼을까?
저는 우분투 서버에서 Java 8 (OpenJDK 1.8.0_292) 환경에서
https://example.com 및 https://example.s3.xxx.amazon.com
같은 외부 서버에 접속하는 애플리케이션을 실행하고 있었습니다.
그런데 로컬에서 Eclipse로 실행하면 잘 되는데, 우분투서버 터미널에서는 오류 발생!
이유는 아주 간단했습니다:
💡 Eclipse는 자체적으로 더 최신의 인증서를 신뢰할 수 있게 설정되어 있었고,
터미널의 Java는 신뢰 저장소(truststore)에 인증서가 없었던 것입니다.
🔑 해결 방법은?
🔹 1. 서버 인증서를 추출
openssl s_client -showcerts -connect example.com </dev/null > xxx_cert.pem
🔹 2. Java truststore에 인증서 등록
keytool -importcert -alias xxx_cert \ -keystore /home/truststore/mytruststore.jks \ -file xxx_cert.pem \ -storepass changeit
🔹 3. Java 실행 시 truststore 지정
java \ -Djavax.net.ssl.trustStore=/home/truststore/mytruststore.jks \ -Djavax.net.ssl.trustStorePassword=changeit \ -classpath ... \ com.xxx.MyApp
📎 그리고 추가로...
Amazon S3 같은 서버는 인증서 체인이 길어서,
openssl s_client -showcerts 명령으로 전체 체인을 받아
여러 개의 .crt 파일로 분리해 모두 truststore에 넣어야 했습니다.
🛠 해결 방법 (추가 인증서 등록)
🔹 1. S3 서버의 전체 인증서 체인 다운로드
openssl s_client -showcerts -connect example.s3.xxx.amazon.com </dev/null > s3_chain.pem
🔹 2. 인증서 분리
csplit -sz -f s3_cert_ s3_chain.pem '/-----BEGIN CERTIFICATE-----/' '{*}'
그럼 다음과 같이 s3_cert_00, s3_cert_01 … 식으로 파일이 생성됩니다.
-rw-r--r-- 1 root root 136 Apr 11 09:13 s3_cert_00
-rw-r--r-- 1 root root 3024 Apr 11 09:13 s3_cert_01
-rw-r--r-- 1 root root 1756 Apr 11 09:13 s3_cert_02
-rw-r--r-- 1 root root 1878 Apr 11 09:13 s3_cert_03
-rw-r--r-- 1 root root 2165 Apr 11 09:13 s3_cert_04
-rw-r--r-- 1 root root 8959 Apr 11 09:13 s3_chain.pem
🔹 3. truststore에 각 인증서 등록
keytool -importcert -alias s3_cert_00 -keystore /home/truststore/mytruststore.jks -file s3_cert_00 -storepass changeit -noprompt
keytool -importcert -alias s3_cert_01 -keystore /home/truststore/mytruststore.jks -file s3_cert_01 -storepass changeit -noprompt
keytool -importcert -alias s3_cert_02 -keystore /home/truststore/mytruststore.jks -file s3_cert_02 -storepass changeit -noprompt
keytool -importcert -alias s3_cert_03 -keystore /home/truststore/mytruststore.jks -file s3_cert_03 -storepass changeit -noprompt
keytool -importcert -alias s3_cert_04 -keystore /home/truststore/mytruststore.jks -file s3_cert_04 -storepass changeit -noprompt
✅ 등록 확인해 볼수도 있습니다.
keytool -list -keystore /home/truststore/mytruststore.jks -storepass changeit | grep s3_cert_
결과 예시..
s3_cert_01, Apr 11, 2025, trustedCertEntry,
s3_cert_02, Apr 11, 2025, trustedCertEntry,
s3_cert_03, Apr 11, 2025, trustedCertEntry,
s3_cert_04, Apr 11, 2025, trustedCertEntry,
🔹 4. 다시 실행
java \ -Djavax.net.ssl.trustStore=/home/truststore/mytruststore.jks \ -Djavax.net.ssl.trustStorePassword=changeit \ -classpath ... \ com.xxx.MyApp
✅ 요약
Java가 서버의 인증서를 신뢰하지 않음 | truststore에 인증서 등록 |
인증서 체인 전체가 없으면 에러 발생 | openssl s_client -showcerts로 체인 전체 확보 |
Eclipse에서는 되는데 터미널은 안 됨 | Eclipse는 자체 설정 or 다른 JDK를 사용할 수 있음 |
🧭 결론
이 예외는 Java의 보안 설정이 잘 작동하고 있다는 뜻이기도 합니다.
단지 우리가 신뢰 인증서를 수동으로 추가해줄 필요가 있을 뿐이죠.
한 번 해결해두면 앞으로는 안정적으로 통신할 수 있습니다!
🔧 Java SSLHandshakeException 해결? 업그레이드만이 답은 아니다
💡 흔한 첫 번째 반응
"아, Java 버전이 오래돼서 인증서를 못 인식하나 보네.
그냥 Java 11이나 17로 업그레이드하면 되지 않을까?"
맞습니다.
최신 JDK는 최신 루트 인증서가 내장되어 있어서,
SSLHandshakeException 문제가 사라질 가능성이 높습니다.
하지만 정말로 그냥 업그레이드해도 될까요?
⚠️ Java 업그레이드가 쉽지 않은 이유들
1️⃣ 삭제된 패키지들
Java 11부터는 다음과 같은 익숙한 패키지들이 완전히 제거되었습니다:
- javax.xml.bind (JAXB)
- javax.annotation
- javax.activation
- javax.ws.rs.*
- javax.jws.*
👉 즉, 예전 코드가 있다면 컴파일 자체가 안 됩니다.
2️⃣ 모듈 시스템(Jigsaw) 도입
Java 9부터 도입된 모듈 시스템 때문에
com.sun.* 같은 내부 API 접근이 제한되고,
라이브러리들도 모듈 간 의존성 문제로 예상치 못한 충돌이 생길 수 있습니다.
3️⃣ 빌드 도구 호환성
- Maven: 3.6 이상 권장
- Gradle: 6.x 이상 권장
- 일부 구버전 플러그인들은 Java 11 이상에서 작동하지 않을 수 있습니다.
4️⃣ 프레임워크 호환성
- Spring Boot 1.x → Java 11 미지원
- Hibernate, Tomcat, Kafka 등도 버전에 따라 Java 11 미호환
👉 실무에서는 관련 라이브러리 전체를 함께 업그레이드해야 합니다.
5️⃣ 서버 환경까지 바꿔야 할 수도...
- Tomcat이나 JBoss 등 서버 구성도 Java 버전과 엮여 있기 때문에
운영 환경 전체에 영향을 줄 수 있습니다.
실시간 눈, 비구름, 위성영상, 레이더영상 관찰
안드로이드 무료 다운로드
날씨위성영상 라이브 - (태풍 구름 눈 비 CCTV) - Google Play 앱
실시간으로 위성영상, 레이더영상을 확인하세요
play.google.com
앱스토어 무료다운로드
'start linux' 카테고리의 다른 글
[Linux] 우분투 MySQL 시작/정지/상태 보는 방법 (0) | 2022.08.03 |
---|---|
[LINUX] vim color scheme 주석 색깔이 눈 아파 (2) | 2022.08.02 |
[GNU bash shell command] ls 파일 갯수 세기 (0) | 2022.07.06 |
[GNU bash shell command] 파일 삭제 rm date 날짜 시간 응용하기 (0) | 2022.07.05 |
[ Linux ] AWS Ubuntu tomcat 9 설치하기 (0) | 2021.09.17 |