- 에러 로그
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
- 원인
Java에서는 따로 관리하는 신뢰하는 인증서 목록이 존재하는데 이 파일에 호출하는 도메인 인증서의 루트 인증서가 등록되어 있지 않을때 발생함.
- 해결 방법
1. 인증서 목록에서 존재 여부 찾기
1.1. 조회 명령어 ( 인증서 목록이 2개니 cacerts, jssecacerts 중에서 사용하는 파일에서 조회 - 확인은 아래 "테스트 방법" 에 존재 )
* keytool -list -v -keystore ${JAVA_HOME}/jre/lib/security/cacerts -storepass changeit | grep -A 10 -B 10 "Thawte"
* keytool -list -v -keystore ${JAVA_HOME}/jre/lib/security/jssecacerts -storepass changeit | grep -A 10 -B 10 "Thawte"
** -v : 자세한 keystore 항목 리스트
** -keystore <keystore> : keystore 이름
** -storepass changeit : 비밀번호
** -A 10 : 특정 문자열 이후 10줄
** -B 10 : 특정 문자열 이전 10줄
2. 인증서 추출
* 인증서 제공 기관에서 다운로드 또는 해당 도메인에서 추출
3. 인증서 keystore에 추가
3.1. 다운로드 받은 인증서를 서버에 업로드
3.2. 해당 인증서 경로로 이동
3.3. su root 로 권한 변경
3.4. keytool을 이용하여 keystore에 추가 ( 사용하는 인증서 목록 cacerts, jssecacerts 중에서 사용하는 곳에 추가 )
* keytool -import -keystore ${JAVA_HOME}/jre/lib/security/jssecacerts -file "DigiCertGlobalRootG2.crt" -storepass changeit -alias "digicertglobalrootg2"
** -file <filename> : 추가할 인증서 파일명
** -alias <alias> : 추가할 인증서 파일의 별칭
* 중복시 삭제 명령어 : keytool -delete -alias digicertglobalrootg2 -keystore ${JAVA_HOME}/jre/lib/security/jssecacerts -storepass changeit
3.5. 인증서 추가 여부 확인에 "y" 입력
3.6. 추가 완료되었다면 테스트
3.7. 테스트 완료되었다면 서비스 재기동
- 테스트 방법
1. su root 로 권한 변경
2. vi SSLChecker.java
3. 테스트 소스 복사 후 저장
4. javac SSLChecker.java 로 테스트 소스 컴파일
5. java SSLChecker <도메인> <포트> 로 도메인 연결 테스트
* java SSLChecker tistory.com 443
** Error: Could not find or load main class SSLChecker 에러 발생시 : java -cp . SSLChecker tistory.com 443
* 사용하는 인증서 파일을 보고 싶은 경우
** -Djavax.net.debug=ssl 옵션 추가 : java -cp . -Djavax.net.debug=ssl SSLChecker tistory.com 443
** 출력의 최상단에 아래 예시와 같이 확인 가능.
※ -Djavax.net.debug=ssl 옵션 출력 예시
keyStore is :
keyStore type is : jks
keyStore provider is :
init keystore
init keymanager of type SunX509
trustStore is: [JAVA HOME경로]/jre/lib/security/jssecacerts
trustStore type is : jks
trustStore provider is :
init truststore
- 테스트 SSLChecker.java 파일 소스
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;
public class SSLChecker {
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("Usage: "+SSLChecker.class.getName()+" <host> <port>");
System.exit(1);
}
try {
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(args[0], Integer.parseInt(args[1]));
//sslsocket.setEnabledProtocols(new String[] {"TLSv1.2"}); // TLS설정 : TLSv1, TLSv1.1, TLSv1.2
SSLParameters sslparams = new SSLParameters();
//sslparams.setProtocols(new String[] {"TLSv1.2"}); // TLS설정 : TLSv1, TLSv1.1, TLSv1.2
sslparams.setEndpointIdentificationAlgorithm("HTTPS");
sslsocket.setSSLParameters(sslparams);
InputStream in = sslsocket.getInputStream();
OutputStream out = sslsocket.getOutputStream();
// Write a test byte to get a reaction :)
out.write(1);
while (in.available() > 0) {
System.out.print(in.read());
}
System.out.println("Successfully connected");
} catch (Exception exception) {
exception.printStackTrace();
System.exit(1);
}
}
}
'IT > Java' 카테고리의 다른 글
Quartz 스케줄러 사용하기 (0) | 2020.06.15 |
---|
댓글