에러 내용
- HTTPS 통신과 관련하여 인증서 문제가 발생했을 경우 나타남
에러 원인
1. 신뢰할 수 없는 CA 인증서 경우
- 새로운 CA로부터 가져온 인증서가 아직 신뢰할 수 없거나 애플리케이션이 CA가 없는 구형 버전에서 실행 중인 경우
- 해결 방법
InputStream에서 특정 CA 가져오기 → CA를 사용하여 keystore 생성 → keystore를 사용하여 TrustManager 생성 → TrustManager를 통해 SSLContext 초기화 → 인증서 확인을 위해 CA를 사용
(TrustManager에서 신뢰할 수 있는 유일한 CA)
// Load CAs from an InputStream
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(new FileInputStream("인증서 파일"));
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
// Tell the URLConnection to use a SocketFactory from our SSLContext
URL url = new URL("URL 주소");
HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
InputStream in = urlConnection.getInputStream();
copyInputStreamToOutputStream(in, System.out);
2. 자체 서명한 사설 인증서인 경우
- 개발 단계에서 CA가 아닌 사설 인증서를 사용할 경우 HttpsURLConnection을 통한 connect 과정에서 해당 에러를 마주칠 수 있음
- 해결방법
TrustManager를 생성한 뒤 이를 통해 SSLContext를 초기화 → 모든 인증서 연결 허용
※ 해당 방법은 보안에 취약하므로 주의할 것 (CA 인증된 공식 인증서를 사용해야 보안에 적합)
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType){
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} };
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
3. 중간 CA가 존재하는데 누락된 경우
참고 링크
https://developer.android.com/training/articles/security-ssl?hl=ko#java
HTTPS 및 SSL을 사용한 보안 | Android 개발자 | Android Developers
HTTPS 및 SSL을 사용한 보안 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 현재 기술적으로 전송 계층 보안(TLS)이라고 알려진 보안 소켓 레이어(SSL)는 클라이
developer.android.com
'Spring > TroubleShooting' 카테고리의 다른 글
java.lang.IllegalArgumentException: Cannot generate variable name for non-typed Collection parameter type (0) | 2024.04.11 |
---|---|
@Pathvariable 슬래시(/) 처리 방법 (0) | 2024.03.12 |
Sqlite LocalDateTime 적용 문제 (0) | 2024.02.19 |
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name~ (0) | 2024.01.08 |
Bean 수동 주입 방법 (@Autowired로 빈 주입 실패 시) (0) | 2024.01.04 |
댓글