Java 애플리케이션에서 암호화 통신 설정하기 (사설 인증서편)
TOC
- Overview
- HTTPS 통신에서 인증서가 하는 일
- 사설 인증서와 공인 인증서
- Java 애플리케이션의 신뢰 저장소
- 전체 설정 흐름
- 이 시리즈에서 다루지 않는 것
- Conclusion
Overview
Java 애플리케이션에서 사설 인증서를 설정하고 암호화 통신을 진행하는 방법을 다룬다.
공인 인증서를 사용하는 HTTPS는 대부분의 운영체제와 JVM이 이미 신뢰할 수 있는 인증서 목록을 가지고 있어 별도 설정 없이 동작한다.
반면 사설 인증서는 애플리케이션이 해당 인증서를 신뢰하도록 별도 설정해야 한다.
이 시리즈에서는 다음 흐름을 다룬다.
사설 CA 인증서 준비
↓
PKCS12 truststore 생성
↓
JVM에 truststore 로드
↓
HTTPS client 생성
↓
사설 HTTPS 서버 호출
HTTPS 통신에서 인증서가 하는 일
HTTPS는 HTTP 통신에 TLS를 적용한 방식이다.
TLS 연결을 시작할 때 클라이언트는 서버가 보낸 인증서를 확인한다. 이때 다음 내용을 검증한다.
- 인증서의 유효 기간
- 요청한 호스트명과 인증서의 이름이 일치하는지
- 인증서가 신뢰할 수 있는 CA에서 발급되었는지
- 인증서 체인이 올바르게 연결되는지
검증에 성공하면 클라이언트와 서버는 암호화 통신에 사용할 세션 키를 협상한다. 이후 HTTP 요청과 응답은 암호화된 연결을 통해 전달된다.
따라서 인증서는 통신 내용을 직접 암호화하는 파일이라기보다, 서버의 신원과 신뢰 여부를 확인하는 데 사용된다.
사설 인증서와 공인 인증서
공인 인증서는 브라우저와 운영체제, JVM이 기본적으로 신뢰하는 CA에서 발급된다.
서버 인증서
↓
공인 CA
↓
운영체제 또는 JVM의 기본 신뢰 목록
사설 인증서는 조직이나 개발 환경에서 직접 관리하는 CA를 기준으로 발급된다.
서버 인증서
↓
사설 CA
↓
애플리케이션 또는 JVM의 별도 신뢰 설정
사설 CA는 기본 JVM truststore에 포함되어 있지 않다. 따라서 Java 애플리케이션이 사설 HTTPS 서버에 연결하려면 사설 CA 인증서를 truststore에 등록해야 한다.
서버 인증서 자체를 무조건 등록하기보다, 해당 서버 인증서를 발급한 CA 인증서를 truststore에 등록하는 방식이 일반적이다.
Java 애플리케이션의 신뢰 저장소
JVM은 HTTPS 서버 인증서를 검증할 때 truststore를 참고한다.
truststore는 신뢰할 수 있는 CA 인증서 목록을 저장하는 파일이다. 반대로 keystore는 애플리케이션이 자신의 개인키와 인증서를 보관할 때 사용한다.
일반적인 서버 인증 검증은 다음과 같이 동작한다.
서버 인증서 수신
↓
인증서 체인 확인
↓
truststore에서 신뢰할 CA 확인
↓
검증 성공 또는 TLS handshake 실패
사설 CA를 사용하는 경우에는 다음과 같은 별도 truststore를 만들 수 있다.
private-ca-truststore.p12
JVM이 이 파일을 읽도록 설정하면 애플리케이션은 사설 CA가 발급한 서버 인증서를 신뢰할 수 있다.
단, 모든 HTTP client가 반드시 JVM 기본 truststore를 사용하는 것은 아니다. 애플리케이션이 별도의 SSLContext나 TrustManager를 사용한다면 추가 설정이 필요할 수 있다.
전체 설정 흐름
이 시리즈는 다음 순서로 진행한다.
1. 사설 CA 인증서 준비
서버 인증서의 발급 체인을 확인하고, JVM에 등록할 CA 인증서를 준비한다.
2. PKCS12 truststore 생성
keytool을 사용해 CA 인증서를 PKCS12 형식의 truststore에 등록한다.
private-ca-root.crt
↓
private-ca-truststore.p12
3. JVM에 truststore 로드
애플리케이션 실행 시 JVM에 truststore 경로와 비밀번호를 전달한다.
trustStore
trustStorePassword
trustStoreType
4. HTTPS client 생성
truststore 설정이 적용된 뒤 HTTP client 또는 SSLContext를 생성한다.
5. HTTPS 요청 확인
사설 HTTPS 서버에 요청을 보내고 인증서 검증과 hostname 검증이 모두 성공하는지 확인한다.
각 단계에서 문제가 발생하면 인증서 체인, truststore 경로, 파일 형식, 비밀번호, hostname을 순서대로 확인한다.
이 시리즈에서 다루지 않는 것
이 시리즈는 Java 애플리케이션의 서버 인증서 검증을 중심으로 다룬다.
다음 내용은 범위에서 제외한다.
- 사설 CA와 서버 인증서 직접 발급
- mTLS에서 클라이언트 인증서 설정
- 인증서 갱신 자동화
- GitLab4j, JGit, Feign 등 라이브러리별 세부 설정
- custom
SSLContext구현 - 운영 환경의 인증서 관리 시스템
이 주제들은 기본 JVM truststore 설정을 이해한 뒤 별도 문서로 다루는 편이 적절하다.
Conclusion
Java 애플리케이션에서 사설 HTTPS 서버와 통신하려면 서버 인증서를 발급한 CA를 애플리케이션이 신뢰해야 한다.
전체 과정은 다음과 같다.
사설 CA 확인
→ PKCS12 truststore 생성
→ JVM에 truststore 로드
→ HTTPS client 생성
→ 서버 인증서 검증
→ 암호화 통신
다음 글에서는 사설 CA 인증서를 JVM용 PKCS12 truststore로 만드는 과정을 다룬다.