DevOps
Java 의 keystore에 SSL/TLS Server 인증서를 import 하는 방법
Steven J.S Min
2019. 2. 28. 15:44
SRC: 정광섭님, https://www.lesstif.com/pages/viewpage.action?pageId=12451848
증 상
Java 에서 HTTPS 로 remote 사이트에 연결시 다음과 같은 Exception 이 발생
Caused by: javax.naming.CommunicationException: simple bind failed: <server-name>
[Root exception is 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\]
원 인
다음과 같이 여러 가지 원인이 있을 수 있다.
연결하려는 remote site의 인증서가 신뢰하는 인증기관 인증서 목록(keystore)에 없음
서버/클라이언트간 사용하려는 SSL/TLS 버전이 맞지 않음(Ex:TLS 1.0 만 지원하는 서버에 1.2로 hand shaking 요청등)
SSL/TLS 통신에 사용하려는 cipher suite 가 오래되거나 지원하지 않음. (Ex: JDK 1.8 부터는 RC4 를 사용하려고 하면 에러 발생)
웹 브라우저의 경우 인증서 경로 설정을 참고하여 웹 서버에 Intermediate CA certificate 를 설치한다.
해 결
1번 원인일 경우 현재 구동되는 JDK 의 keystore에 상대방 인증서를 넣어줘야 함
1. gist 에서 InstallCert.Java 를 다운로드
2. 컴파일
3. InstallCert 구동
java - cp ./ InstallCert git.nbnco.net.au
|
4. 다음과 같은 화면이 나오면 1을 눌러서 인증서 저장
Caused by: java.lang.UnsupportedOperationException
at InstallCert$SavingTrustManager.getAcceptedIssuers(InstallCert.java:183)
at sun.security.ssl.AbstractTrustManagerWrapper.checkAlgorithmConstraints(SSLContextImpl.java:926)
at sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(SSLContextImpl.java:872)
at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:814)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
... 2 more
Server sent 2 certificate(s):
1 Subject CN=wiki.modernpug.org
Issuer CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US
sha1 47 0a 15 c4 5d ed 62 0a 4b 18 d5 d8 58 14 42 5d 36 e0 d5 8f
md5 3a 0d ab ce 27 be dd bd e5 c1 d5 e8 b6 25 aa eb
2 Subject CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US
Issuer CN=DST Root CA X3, O=Digital Signature Trust Co.
sha1 e6 a3 b4 5b 06 2d 50 9b 33 82 28 2d 19 6e fe 97 d5 95 6c cb
md5 b1 54 09 27 4f 54 ad 8f 02 3d 3b 85 a5 ec ec 5d
Enter certificate to add to trusted keystore or 'q' to quit: [1]
2
서버가 2 개의 인증서를 전송했는데 2번째가 Let's Encrypt 의 CA 인증서이므로 2번을 선택해서 저장해야 한다.
5. 다음과 같은 메시지가 나오고 저장됨. keystore 명과 alias 명을 기억
Added certificate to keystore 'jssecacerts' using alias 'letsencrypt'
6. keytool 로 keystore에서 인증서 추출 (KeyStore의 암호는 changeit 이라 가정!)
keytool -exportcert -keystore jssecacerts -storepass changeit - file output.cert - alias letsencrypt
|
7. 현재 JDK 의 keystore에 cert import
keytool -importcert -keystore ${JAVA_HOME} /jre/lib/security/cacerts -storepass changeit - file output.cert - alias letsencrypt
|
이미 존재할 경우 다음 명령어로 삭제
같이 보기