Table of Contents
unable to find valid certification path to requested target
https 통신을 하는 상황에서 인증서가 없다거나,
사실인증서로 인증되고 있는 경우,
또는 정상적인 인증서라고 해도 JDK 에 포함되어 있지 않는 인증서를 이용하는 경우,
위와같은 오류가 발생한다.
해결책 01
JDK 에 포함되어 있는 인증기관에서 발급한 인증서를 설정해 준다.
해결책 02
아래 방법으로 인증서 오류를 무시한다.
public class NetworkUtil {
public static void disableSslVerification() {
try {
// ============================================
// trust manager 생성(인증서 체크 전부 안함)
TrustManager[] trustAllCerts =new TrustManager[] {new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
public void checkClientTrusted(X509Certificate[] certs, String authType){ }
public void checkServerTrusted(X509Certificate[] certs, String authType){ }
}};
// trust manager 설치
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// ============================================
// host name verifier 생성(호스트 네임 체크안함)
HostnameVerifier allHostsValid = (hostname, session) -> true;
// host name verifier 설치
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
}
}
https 통신전 위 메소드를 호출해서 인증서 체크를 임시로 정지시킨다.
@SpringBootApplication
public class WarehousewebApplication {
public static void main(String[] args) {
NetworkUtil.disableSslVerification();
SpringApplication.run(WarehousewebApplication.class, args);
}
}
한번만 호출해 주면 이후의 모든 https 통신에서 인증서 체크를 하지 않는다.
해결책 03
위 2번 해결책은 보안상 위험성이 있으므로,
Let’s Encrypt 에서 발급한 인증서를 이용하는 방법이 더 좋다.
Java 9 이상
전부 지원합니다.
Java 8
아래에 표시한 버전부터 JDK 에 Let’s Encrypt 인증서가 포함되어 있으므로,
별다른 작업없이 정상적으로 인증서를 사용할 수 있다.
- Oracle JDK 8 : 8u101
- OpenJDK 8 : 운영체제에 따라 다름
- Amazon Corretto 8 : 8u262
- Zulu OpenJDK 8 : 8u112
- AdoptOpenJDK 8 : 8u262
Java 7
역시 배포판별로 제각각입니다.
Java 8 이후 버전으로 버전업을 하는 것을 추천합니다.
이외 버전
아래 명령으로 발급받은 인증서를 수동으로 추가해 주어야 한다.
또한 매 3개월마다 인증서를 갱신해야 하므로,
아래 명령을 매달 실행해 주어야 한다.
keytool -trustcacerts \
-keystore $JAVA_HOME/jre/lib/security/cacerts \
-storepass changeit \
-noprompt \
-importcert \
-file /etc/letsencrypt/live/hostname.com/chain.pem
https://blog.arkey.fr/2017/10/19/self-signed-certificates-in-java.en/