字节流的博客

JavaMail Handshake Failure 解决

1. Handshake_Failure

之前用 javax.mail:mail:1.4.7 的包,结合 org.springframework.mail.javamail.JavaMailSenderImpl 写的通过腾讯企业邮箱(exmail)后台邮件发送的服务,跑的好好的,前两天在另一个项目中用,抛异常了。然后用 Python 写的一个发送邮件的脚本,用同样的用户名,密码和相应的配置却可以成功发送。证明腾讯企业邮箱服务器是没有问题的。然后查看了下异常,是这样的:

1
2
3
4
5
6
7
Mail server connection failed; nested exception is javax.mail.MessagingException: 
Could not connect to SMTP host: smtp.exmail.qq.com, port: 465;
nested exception is: javax.net.ssl.SSLHandshakeException: Received fatal
alert: handshake_failure. Failed messages: javax.mail. MessagingException:
Could not connect to SMTP host: smtp.email.qq.com, port: 465;
nested exception is:javax.net.ssl.SSLHandshakeException: Received fatal
alert: handshake_failure

很明显是 SSL 握手出了问题。然后用 Wireshark 看了下,Client Hello 之后,服务端就回了 handshake failure 的包。然后对比和 Python 发送邮件握手过程,发现 Python 提供的加密套件有几十种,而 Java 握手就提供了十几种。并且 exmail server 选择 Python 的加密套件是 Java 邮件发送服务握手过程中未提供的。并且通过 ssllabs 对 exmail.qq.com 的 Handshake Simulation可知,其证书支持 Java 8u31,而我的 Java 版本是 Java 8u65,所以异常的抛出应该是 Java 提供的加密套件问题。

2. JCE

JCE 即 Java 加密扩展(JCE, Java Cryptography Extension),是一组提供加密、密钥生成、密码协议和消息认证码(MAC, Message Authentication Code)算法的框架和接口包,支持包括对称密码、不对称密码、分组密码、流密码。该软件还支持安全流和密封对象。

对应我的 Java 8 的版本,下载 JCE ,解压并将其中的两个 jar 包:local_policy.jarUS_export_policy.jar 复制到 %JAVA_HOME%\jre\lib\security 即可。

重新启动应用,邮件可以正常发送了。😃

参考

  1. http://stackoverflow.com/questions/36189855/javamail-could-not-connect-to-smtp-host-ssl-465-handshake-failure
  2. http://www.jianshu.com/p/5d907afab9fb
  3. http://www.car.com.blog.163.com/blog/static/361458462007819101938953/
  4. https://www.ssllabs.com/ssltest/analyze.html?d=exmail.qq.com
Thanks! 😊