디버깅∕오류해결

[Spring Java] javax mail Could not convert socket to TLS

728x90

JAVA 스프링 프로젝트를 AWS로 배포하는 과정에서 이메일 전송 오류가 발생했다.

DB 연결까지 잘 되었는데 회원가입, 비밀번호 찾기 등등 메일 전송이 되지 않아서 문제를 찾아 해결했다.

 

👾 오류메세지 javax.mail.MessagingException

javax mail Could not convert socket to TLS;

 

오류 발생 화면

 

메인 원인이 SSLHandshakeException 인것을 확인하고, 구글링한 결과 서버/클라이언트간 사용하려는 SSL/TLS 버전이 맞지 않을 경우 해당 오류가 발생한다는 사실을 알아냈다.

그래서 mailSender 빈 객체를 선언하는 context 파일에서 props 속성코드를 추가했다.

 

기존코드

    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="smtp.gmail.com" />
        <property name="port" value="587" />
        <property name="username" value="이메일주소" />
        <property name="password" value="이메일계정비밀번호" />
        <property name="javaMailProperties">
            <props>
                <prop key="mail.smtp.starttls.enable">true</prop>
                <prop key="mail.smtp.auth">true    </prop>
                <prop key="mail.transport.protocol">smtp</prop>
                <prop key="mail.debug">true</prop>
            </props>
        </property>
    </bean>

기존 prop에 ssl 관련 코드를 추가해주었다.

특히, 프로토콜 관련 예외처리를 해주기위해 TLS 버전을 지정해서 해당 오류를 해결했다.

 

추가 코드

<prop key="mail.smtp.ssl.trust">smtp.gmail.com</prop>
<prop key="mail.smtp.ssl.protocols">TLSv1.2</prop>

 

완성 코드

    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="smtp.gmail.com" />
        <property name="port" value="587" />
        <property name="username" value="이메일주소" />
        <property name="password" value="이메일계정비밀번호" />
        <property name="javaMailProperties">
            <props>
                <prop key="mail.smtp.starttls.enable">true</prop>
                <prop key="mail.smtp.auth">true    </prop>
                <prop key="mail.transport.protocol">smtp</prop>
                <prop key="mail.debug">true</prop>
                <prop key="mail.smtp.ssl.trust">smtp.gmail.com</prop>
                <prop key="mail.smtp.ssl.protocols">TLSv1.2</prop>
            </props>
        </property>
    </bean>

 

여기까지 하고나면 이 다음으로 권한관련 오류가 발생할 가능성이 있다.

javax.mail.AuthenticationFailedException

 

이 경우, 지메일 계정에서 보안 부분을 해결하면 된다.

권한 관련 오류 해결 방법은 해당 티스토리 내용을 참고했다.

https://greensul.tistory.com/31

 

변경된 내용을 저장하고, 다시 war 파일로 만들어 우분투를 통해 서버에 배포했더니 이메일이 성공적으로 전송됐다. 

 

생각보다 간단하게 해결되었지만, 난 원인이 궁금하다!!

 


 

근본 원인을 파악해보자

tls version을 지정해주면 왜 오류가 해결되는 건지 생각해보기 (tls는 ssl의 구버전임)
브라우저의 tls or ssl 버전과 tomcat server의 tls ssl 버전이 맞지 않아서?

 

초기 SSL Protocol 을 기반으로 개발된 TLS 는 클라이언트-서버 간의 통신 채널을 보호하고 암호화 하기 위해 사용되는 암호화 프로토콜이다.

 

메일 전송에 사용되는 프로토콜을 TLSv1.2 로 지정해 준 뒤 해결되는 것으로 보아 기본적으로 지정되는 TLS 버전이 기존 지원이 중단된 TLS 버전 1.0 이나 1.1으로 사용되는 예외가 있어서 발생하는 문제로 파악했다. 구 버전인 TLS 1.0, 1.1 은 POODLE 과 BEAST 와 같은 여러 공격에 취약한 이유로 2020년 이후부터 주요 브라우저에서는 지원을 중단하였기 때문이다.

 

* TLS 1.2 를 지원하기 위해서는 JDK 1.7 이상이 필요하다

 

 

 

참고 :

How to determine if a browser is using an SSL or TLS connection?

javamail-could-not-convert-socket-to-tls-gmail

java-sslhandshakeexception

[한국전자인증 2019 공지] 웹 브라우저 TLS 1.0, TLS 1.1 프로토콜 지원 중단 예정

SSL 통신을 위한 WAS 내 Java 설정_https 호출

728x90