250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- spring
- stream api
- apache.poi
- DevOps
- ORM
- Jenkins
- 엑셀 업로드
- 보안
- java
- sqlserver
- rabbitmq
- 자동빌드
- Stream
- mssql
- mom
- 자바8
- JQuery
- QueryDSL
- poi
- jqGrid
- 제이쿼리그리드
- 대용량 업로드
- 스트림
- JPA
- 자동배포
- ci/cd
- MessageQueue
- Javascript
- 그리드
- docker
Archives
- Today
- Total
개발 메모장
[Java] keytool을 이용한 루트 인증서 등록(SSLHandshakeException) 본문
728x90
[org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler]
Unexpected error occurred in scheduled task.
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
- API를 실행하는 서비스에서 갑자기 위와 같은 에러가 발생했습니다.
- 방화벽 등을 체크해 봤지만 이유를 찾지 못하던 중 API 서버 측에서 SSL을 변경했다고 합니다.
- 처리되어야 하는 데이터가 있기에 우선 원복 요청을 하였고 SSL을 변경함에 따른 조치 이행 및 에러포인트가 여러 곳일 수 있다는 가정 하에 아래와 같은 처리를 통해 해결하였습니다.
간략하게 SSL과 TLS가 무엇인지 알아보도록 하겠습니다.
#. SSL 이란?
- SSL은 Security Socket Layer로 90년대 중반에 개발된 인터넷 통신 보안 프로토콜입니다.
- SSL은 OSI 모델 중 전송계층에서 작동하며 웹 브라우징 세션 보안을 위해 네트워크를 통한 클라이언트-서버 간 통신에 사용하는 HTTP, SMTP, FTP 등의 프로토콜에 대한 암호화, 인증 등의 보안 기능을 제공합니다. HTTP + SSL을 적용한 것인 HTTPS가 대표적인 예입니다.
- SSL은 1.0, 2.0, 3.0 등 여러 버전이 있습니다.
#. TLS 란?
- TLS는 SSL의 보안 취약점을 해결 및 개선하기 위해 SSL 후속으로 개발되었습니다.
- SSL과 동일한 목적으로 네트워크를 통한 클라이언트-서버 간 통신의 보안을 위한 암호화 및 데이터 무결성, 인증 등의 기능을 제공합니다.
- TLS는 TLS1, TLS1.1, TLS1.2, TLS1.3의 버전이 있으며 1.0과 1.1은 보안 취약점으로 인해 거의 사용되지 않습니다.
- TLS도 SSL과 동일하게 OSI 모델 중 전송계층에서 작동하며 HTTPS, SMTPS, FTPS 등의 프로토콜에 대한 통신을 보호합니다.
#. TLS 버전 문제일까?
- API 통신을 위해 사용하고 있던 Java와 WAS(톰캣)의 버전이 현재로선 거의 사용하지 않는 7 버전입니다.(자바 1.7, 톰캣 7)
- WAS로 사용하는 Tomcat > Connector > sslEnabledProtocols에서 명시적으로 설정하지 않는 경우 JVM의 기본 TLS버전을 상속하게 됩니다.
- 자바 1.7은 일반적으로 TLS1.0을 지원하기에 기본적으로 TLS1.0을 사용합니다.
- 서버 측에서 적용한 SSL이 버전 문제로 이슈가 있는 것이 아닌지 생각이 들어 Tomcat > server.xml에서 connector 태그에 sslEnabledProtocols을 설정했습니다.
- 결과적으론 이 문제는 아니었습니다.
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"
sslEnabledProtocols="TLSv1, TLSv1.1, TLSv1.2" />
#. 인증서 발급 기관의 변경
- 서버 측에서의 SSL 적용에 대한 내용을 고지받지 못한 상태였기에 이 문제는 아닐 거라 생각했습니다.
- 확인한 결과 기존 SSL 인증서의 발급기관과 신규 적용한 SSL 인증서의 발급기관이 달랐습니다.
- 그렇기에 먼저 해당 기관의 인증서가 있는지 콘솔을 통해 확인합니다.
- 사용한 명령어는 아래와 같은 역할을 합니다.
-list : 인증서 저장소의 목록 조회
-v : 상세 조회
-keystore : 인증서 저장소 경로 입력
keytool -list -v -keystore "D:\자바 폴더 경로\jre\lib\security\cacerts"
- 위 명령어를 입력하면 비밀번호를 묻는데, 비밀번호의 디폴트는 changeit이며 아래와 같이 목록이 나옵니다.

- 이곳에 해당 인증서의 발급기관에 대한 내용이 없었습니다.
- 따라서 API 통신 시 해당 웹에 접근가능하도록 java > cacerts에 신뢰할 수 있는 기관 인증서로 등록해줘야 합니다.
#. 인증서 다운로드 받기
- 크롬 기준으로 설명드리자면 API 통신을 위한 웹에 접속하여
주소창 왼쪽의 버튼 > 이 연결은 안전합니다. > 인증서가 유효함 > 인증서뷰어 > 세부정보 > 우측 하단 내보내기 클릭 > 저장 - powershell 관리자 권한으로 실행
- 자바 폴더 경로는 환경변수로 만든 {JAVA_HOME}으로 입력 가능합니다. - 사용한 명령어는 아래와 같은 역할을 합니다.
-import : import 함을 명시
-alias : 별칭 설정
-keystore : 인증서 저장소 경로 입력
-storepass : 저장소 암호 입력
-file : 인증서 파일 경로 입력
keytool.exe -import -alias 별칭 -keystore "D:\자바 폴더 경로\jre\lib\security\cacerts" -storepass changeit -file "d:\인증서 경로\인증서 파일명"
- 아래와 같이 이 인증서를 신뢰합니까?라고 묻고 y 또는 yes를 입력하면 저장소에 추가됩니다.

- 이렇게 처리하면 정상적으로 API가 통신하는 것을 확인할 수 있습니다.
- 결론적으론 TLS 버전 문제는 아니었으며, 인증서의 발급기관이 클라이언트 내 신뢰할 수 있는 기관에 없었기에 오류가 발생했습니다.
- 이러한 특이사항이 있을 경우엔 더더욱 클라이언트에게 미리 알려야 하지 않았을까 싶기도 하고 먼저 체크했다면 좀 더 수월히 진행 됐을 텐데라는 아쉬움이 남습니다.
===========================================================
틀린 내용이 있거나 이견 있으시면 언제든 가감 없이 말씀 부탁드립니다!
===========================================================
728x90
'Java' 카테고리의 다른 글
[Java] HTTPS 통신 시 인증서 관련 오류(DH keypair) (1) | 2024.11.05 |
---|---|
[Java] 함수형 인터페이스(Functional Interface) (0) | 2024.06.13 |
[Java] Apache.POI 엑셀 업로드 구현 - DB 처리(3/3) (1) | 2024.01.05 |
[Java] Apache.POI 엑셀 업로드 구현 - Controller(2/3) (2) | 2024.01.04 |
[Java] Apache.POI 엑셀 업로드 구현 - Handler(1/3) (1) | 2024.01.03 |