2024. 4. 25. 11:23ㆍ오류조치
외부 사이트와 API 연동 중 localhost (ssl 미적용)에서는 정상 작동 되던 것이 테스트 서버(ssl 적용)에서 통신 에러가 발생했다. 오류 문구는 remote host closed connection during handshake
위 오류의 원인과 발생 시 해결 및 조치 방법을 알아보자.
1. 원인
ssl 이 강화되면서 TSLv1.2 , TSLv1.3등 통신 보안 형식이 다양화 되었다. 또, ciphers 설정과 같이 암호화 방식도 다양화 되어 클라이언트와 서버단의 통신 규칙을 맞춰줘야한다.
2. 오류조치
1) 상대방 서버 통신규칙 알기
https://www.ssllabs.com/ssltest/
위 사이트에서 상대방 도메인을 넣으면 어떤 형식으로 통신 가능한지 알 수 있다.
내가 통신하는 사이트는 TSL 1.3, TSL 1.2를 지원한다. 다만 크롬의 경우 TSL 1.3을 통신한다.
2) TSL 1.2, TSL 1.3 설정
TSL 버전을 설정하는 방법은 두가지가 있다.
- JAVA 소스 내 수정
: 외부 api 호출 전 소스 내에 아래와 같이 소스를 추가한다.
System.setProperty("https.protocols", "TLSv1.2");
- 톰캣 설정 수정
: 톰캣의 server.xml 파일에서 connector을 아래와 같이 수정한다.
protocols="TLSv1.3,TLSv1.2" , ciphers 추가
<Connector port="449" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" URIEncoding="utf-8" >
<SSLHostConfig protocols="TLSv1.3,TLSv1.2"
ciphers="TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,
TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA">
<Certificate certificateKeystoreFile="/conf/SSL/STAR.abc.co.kr.jks"
certificateKeystorePassword="123"
type="RSA" />
</SSLHostConfig>
</Connector>
3) TSL 1.3 사용을 위한 톰캣 jdk 버전 변경
TSL1.3은 JDK 11 이상이 지원된다.
아래 링크에서 JDK 11 설치 후
https://jdk.java.net/java-se-ri/11
tomcat 폴더의 bin 폴더 내에 setenv.bat 파일을 만들어 설정을 한다.
@echo off
SET "JAVA_HOME=C:\Program Files\Java\jdk-11"
SET "JRE_HOME=%JAVA_HOME%"
SET "PATH=%JAVA_HOME%\bin;%PATH%"
위와 같이 설정하면 TSL 1.3 통신도 정상적으로 가능하다.
만약 위와 같이 해도 오류가 발생하면 SSL 상세 오류 코드확인이 가능하다.
디버깅을 위해 setenv.bat 파일 내에 아래 코드를 추가한다.
SET "CATALINA_OPTS=%CATALINA_OPTS% -Djavax.net.debug=ssl,handshake"