JavaMail无法连接到SMTP主机SSL 465:handshake_failure

时间:2016-03-23 22:24:44

标签: java email smtp javamail

在我的Web服务器提供程序禁用旧安全协议(版本)和密码套件后,我无法再连接到smtpserver。这是我原来的配置,但没有加密通信(SSL,TLS)更长的可能性。

这个问题可能是什么原因?

DEBUG: setDebug: JavaMail version 1.5.5 (JDK 1.7)

enter image description here

当我尝试不使用SSL(在代码中注释)时,它运行正常,因此Web服务器必须存在问题。有趣的事实:Outlook工作正常(使用相同的凭据)!

public static void main(final String[] args) throws Exception {
    System.setProperty("javax.net.debug", "all");

    final Properties props = new Properties();

    // use SSL (worked before ssl-update on mailserver, where old security protocols were disabled)
    props.put("mail.smtp.ssl.socketFactory", "javax.net.ssl.SSLSocketFactory");
    props.put("mail.smtp.socketFactory.port", "465");
    props.put("mail.smtp.socketFactory.fallback", "false");
    props.put("mail.smtp.host", "alfa3022.alfahosting-server.de");
    props.put("mail.smtp.port", "465");
    props.put("mail.smtp.ssl.enable", "true");

    // no ssl (works fine!):
    // props.put("mail.debug", "true");
    // props.put("mail.smtp.host", SMTP_HOST_NAME);
    // props.put("mail.smtp.auth", "true");
    // props.put("mail.smtp.port", 587);

    final Session session = Session.getInstance(props, new javax.mail.Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(getEmailUsername(), getEmailPassword());
        }
    });

    session.setDebug(true);
    final Message msg = new MimeMessage(session);
    final InternetAddress addressFrom = new InternetAddress("test@test.com");
    msg.setFrom(addressFrom);

    // [...] create email object and add contents to msg
    msg.setRecipient(Message.RecipientType.BCC, new InternetAddress("dummy@test.com"));
    Transport.send(msg);

}

当我执行电子邮件服务器的握手模拟时,它告诉我java不工作? https://www.ssllabs.com/ssltest/analyze.html?d=alfa3022.alfahosting-server.de

enter image description here

可能有什么区别或我没看到什么?

2 个答案:

答案 0 :(得分:1)

  

这个问题可能是什么原因?

<强>答:

SSLHandshakeExceptionIOException的子类,因此您不需要明确捕获。大多数开发人员不需要显式捕获,但它可以帮助您更轻松地诊断任何IOException的原因。

应用-Djavax.net.debug=all属性时,与SSLHandshakeException关联的失败将在日志中的算法协商后立即显示。

因此,System.setProperty("javax.net.debug", "all");在您的代码中出错。

  

发生SSLHandshakeException的根本原因是什么?如何   防止它?

<强>答:

SSLHandshakeException的最可能原因是算法支持。 JDK提供了一个名为 JCE Unlimited Strength 的独立软件包,旨在添加比默认情况下更强大的算法支持。 Qualys SSL Labs提供了一个不同的server SSL test,它将枚举服务器支持的算法。

添加更强大的算法:JCE无限强度

在高安全性环境中,加强JDK算法的一种方法是通过JCE Unlimited Strength策略文件。在这种特殊情况下,在JDK 7中替换这些策略文件允许它使用现有算法的更强变体并成功连接。

JCE Unlimited Strength下载:JDK 8JDK 7JDK 6

资源链接:

  1. Diagnosing TLS, SSL, and HTTPS
  2. 您可以尝试使用

    您需要设置证书才能访问SMTP端口。

    System.setProperty("javax.net.ssl.trustStore","key");
    System.setProperty("javax.net.ssl.trustStorePassword","password");
    

    要生成KeyStore和TrustStore,请按照tutorial

    进行操作

    来自Marvin Pinto的答案,

    当您尝试连接的服务器没有来自授权CA的有效证书时,通常会抛出javax.net.ssl.SSLHandshakeException异常。

    简单地说,您尝试连接的服务器很可能使用自签名证书,您必须在Java代码中容纳该证书。 This involves creating a custom KeyStore等。有关完整的实施详细信息,请参阅this Stack Overflow答案。

      

    如果你想完全澄清你的观念,那么请阅读   tutorial用于使用带有JavaMail的SSL

    相关链接:

    1. JAVAMAIL API FAQ
    2. Received fatal alert: handshake_failure through SSLHandshakeException

答案 1 :(得分:-2)

您可以使用openssl测试证书,以及解决握手失败的方法。

openssl s_client -connect mail.alfahosting-server.de:443

当我向你提到的那个主人做过​​时,我实际上得到了:

  

验证返回代码:20(无法获得本地颁发者证书)