SSLHandshakeException : handshake_failure

JEONYUNHWAN·2023년 11월 25일
0

예외잡기

목록 보기
1/1

필자는 사이드프로젝트에서 FCM 푸시 기능 구현을 맡으면서, 로컬에서는 FCM으로 토큰 전송을 진행해서 푸시 알림이 가는데, 실배포 시 알림이 가지 않는 문제를 발견했다. 방화벽 문제인가 싶어서 방화벽도 다 키고 했지만 에러를 잡을 수 없었다.

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131) ~[na:na]
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117) ~[na:na]
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:365) ~[na:na]
	at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293) ~[na:na]
	at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:204) ~[na:na]
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172) ~[na:na]
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1510) ~[na:na]
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1425) ~[na:na]
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455) ~[na:na]
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426) ~[na:na]
	at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:589) ~[na:na]
	at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:187) ~[na:na]
	at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1430) ~[na:na]
	at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1401) ~[na:na]
	at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:220) ~[na:na]
	at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:113) ~[google-http-client-1.42.2.jar!/:1.42.2]
	at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:84) ~[google-http-client-1.42.2.jar!/:1.42.2]
	at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1012) ~[google-http-client-1.42.2.jar!/:1.42.2]
	at com.google.auth.oauth2.ServiceAccountCredentials.refreshAccessToken(ServiceAccountCredentials.java:564) ~[google-auth-library-oauth2-http-1.12.1.jar!/:na]
	... 133 common frames omitted

우선 에러를 살펴보면, SSL 뭐시기 핸드쉐이크 실패다 뭐 이런식으로 나오는데 용어부터 알아보자

HTTPS

  • S -> 보안이고, 보안이 향상된 웹 통신을 하기 위함이 목적이다. http 사이트 들어가기전에 위험! 이러면서 보안 취약점 주의 이런 경고창을 볼 수 있을 것이다. 하지만 https 사이트 이용시 그러한 경고창을 볼 수 없다.

즉, http는 암호화 되지 않는 방법으로 서버에 데이터 전송하기 때문에 보안 위협 가능성이 높기 때문에 서버에 https 프로토콜을 통한 통신을 하는 것이다.

SSL

만약에 우리는 제조업체이다. 제조 업체에서 중요한 거래처가 있는데 이러한 거래를 할때 제 3자가 나서서 인증을 해주는 것을 생각해보라.

  • 위의 예시에서 제 3자가 나서서 인증을 해준다고 했는데 이게 SSL이라고 한다. Secure Sockets Layer 라고 한다. 즉, 클라이언트와 서버간의 통신을 제 3자가 보증을 해주는 문서이다.
  • 클라이언트에서 서버에 접속하면, 서버는 클라이언트에 인증서 전달하고, 클라이언트는 인증서를 확인 후에 데이터를 보내는 식으로 절차를 수행하게 된다.
  • 전달되는 내용을 다른 사람에게 노출 되는 것을 막을 수 있다.
  • 클라이언트가 접속하려는 서버가 신뢰할 수 있는 서버 인지 알 수 있다.
  • 전달되는 내용 변경을 막을 수 있다.

여기서 SSL 핸드쉐이크에서 실패를 했기 때문에 SSL 핸드쉐이크 중에 실패했다는 에러이기 때문에 나의 TLS 1.1, 1.0 사용을 하고 있었고, FCM은 TLS 1.2 사용을 하고 있어 핸드쉐이크 에러가 발생하고 있다는 것을 확인하였다. 따라서 fcm 토큰 초기화 하고 메세지를 보낼때 tls 버전을 강제하고 에러를 잡을 수 있었다.

System.setProperty("https.protocols", "TLSv1.2");
profile
인생은 쓰고, 달콤함은 없다.

0개의 댓글