Java SSL 인증서 검증 흐름 및 확인
외부와 통신하는 기능에 대해 외부 서비스의 SSL이 2세대 인증서로 변경되면서 이에 대해 확인하는 과정을 기록한 것이다
어플리케이션에서 외부 서비스와의 통신을 하는 경우 RestTemplate를 통해 통신을 하는 등 java 단에서 통신을 하는 경우가 있다
이러한 경우 통신의 과정에서 SSL 인증서의 검증은 어떻게 이루어 지는지에 대해 알아보았다
일반적으로 웹사이트에 접속을 하게 되면 SSL 인증서에 대한 검증은 브라우저에서 수행하게 되어있는데
Java 어플리케이션 내에서 https 프로토콜로 통신 하는 경우 SSL 인증서에 대한 검증은 JVM 내에서 이루어지게 되어있다
Java의 SSL 인증서 검증 흐름
Java 어플리케이션 내에서 SSL 인증서의 검증 흐름은 다음과 같다
HttpsURLConnection
↓
SSLContext
↓
TrustManagerFactory
↓
X509TrustManager (실제 검증 수행)
↓
checkServerTrusted
HttpsURLConnection은 네트워크 통신 레벨의 API로 SSL 핸드셰이크를 수행
SSLContext는 SSL 세션의 구성요소에 대한 초기화 및 관리르 수행하고 해당 객체에서 암호화 방식이나 TrustManager를 결정
TrustManagerFactory SSLContext에서 사용할 TrustManager 리스트를 생성하는 역할 수행한다 이 때, JVM "cacerts" 또는 사용자 keyStore를 통해 TrustManager 생성
X509TrustManager는 실제 서버 인증서 체인을 검증하는 역할을 수행하며 "checkServerTrusted" 메소드를 통해 서버가 제공한 인증서 체인을 검증
(RestTemplate도 내부적으로 HttpURLConnection을 사용하고 있어 인증 흐름은 동일)
Java 내 cacerts 확인 방법
cd $JAVA_HOME (JAVA가 설치된 디렉토리로 이동)
cd jre/lib/security (cacerts가 있는 위치로 이동)
# 아래 명령을 수행하면 해당 되는 alias에 대한 CA 인증서 정보를 볼 수 있다
keytool -list -v -keystore ./cacerts -storepass [password, 기본 "changeit"] -alias '[alias 명]'
해당 CA인증서를 확인함으로써 인증서의 세대 교체 등이 발생했을 때 신규 인증서를 어플리케이션에서 검증할 수 있는지 확인할 수 있다
추가
어플리케이션 실행할 때 jvm 옵션으로 아래 옵션을 추가하면 HTTPS 요청이 발생할 때 인증서, TLS 버전, 루트 인증서에 대한 정보를 로그로 확인할 수 있다
-Djavax.net.debug=ssl,handshake,certpath