简体   繁体   English

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

[英]JavaMail Could not connect to SMTP host SSL 465: handshake_failure

after my web-server provider disabled old security protocol(versions) and cipher suites, I am no longer able to connect to the smtpserver.在我的网络服务器提供商禁用旧的安全协议(版本)和密码套件后,我无法再连接到 smtpserver。 this was my original configuration, but no encrypted communication (SSL, TLS) is longer possible.这是我的原始配置,但不再可能进行加密通信(SSL、TLS)。

What could be the source of this problem?这个问题的根源是什么?

DEBUG: setDebug: JavaMail version 1.5.5 (JDK 1.7)

在此处输入图片说明

when I try the same without SSL (commented in code), it works fine, so there has to be a problem with the webserver.当我在没有 SSL 的情况下尝试相同的操作时(在代码中注释),它工作正常,所以网络服务器肯定有问题。 Funny fact: Outlook works just fine (with same credentials)!有趣的事实: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);

}

When I execute a Handshake-Simulation of the email-server it tells me that java is not working??当我执行电子邮件服务器的握手模拟时,它告诉我 java 不工作? https://www.ssllabs.com/ssltest/analyze.html?d=alfa3022.alfahosting-server.de https://www.ssllabs.com/ssltest/analyze.html?d=alfa3022.alfahosting-server.de

在此处输入图片说明

What could be the difference or what am I failed to see?可能有什么不同或我没有看到什么?

What could be the source of this problem?这个问题的根源是什么?

Ans:答:

SSLHandshakeException is a subclass of the IOException , so you do not need to catch is explicitly. SSLHandshakeExceptionIOException的子类,因此您无需明确捕获。 Most developers will not need an explicit catch, but it may help you more easily diagnose the cause of any IOException.大多数开发人员不需要显式捕获,但它可以帮助您更轻松地诊断任何 IOException 的原因。

When applying the -Djavax.net.debug=all property, the failure associated with this SSLHandshakeException would appear immediately after algorithm negotiation in the logs.应用-Djavax.net.debug=all属性时,与此SSLHandshakeException关联的失败将在算法协商后立即出现在日志中。

So, System.setProperty("javax.net.debug", "all");所以, System.setProperty("javax.net.debug", "all"); is making error in your code.在您的代码中出错。

What is the root cause of occuring SSLHandshakeException?发生 SSLHandshakeException 的根本原因是什么? How to prevent it?如何预防?

Ans:答:

The most likely cause for SSLHandshakeException is algorithm support. SSLHandshakeException 最可能的原因是算法支持。 The JDK provides a separate package called JCE Unlimited Strength , designed to add stronger algorithm support than what's available by default. JDK 提供了一个名为JCE Unlimited Strength的单独包,旨在添加比默认情况下可用的算法更强大的算法支持。 Qualys SSL Labs provides a different server SSL test that will enumerate which algorithms a server supports. Qualys SSL Labs 提供了一个不同的服务器 SSL 测试,它将枚举服务器支持的算法。

Adding stronger algorithms: JCE Unlimited Strength添加更强的算法:JCE Unlimited Strength

In a high security environment, one way of strengthening algorithms in the JDK is through the JCE Unlimited Strength policy files.在高安全性环境中,增强 JDK 中算法的一种方法是通过 JCE Unlimited Strength 策略文件。 In this particular case, replacing those policy files within JDK 7 allows it to use the stronger variants of existing algorithms and connect successfully.在这种特殊情况下,替换 JDK 7 中的这些策略文件允许它使用现有算法的更强变体并成功连接。

JCE Unlimited Strength downloads: JDK 8 , JDK 7 , or JDK 6 . JCE Unlimited Strength 下载: JDK 8JDK 7JDK 6

Resource Link:资源链接:

  1. Diagnosing TLS, SSL, and HTTPS 诊断 TLS、SSL 和 HTTPS

You can try with it你可以试试

you need to set certificate, to access the SMTP port.您需要设置证书,才能访问 SMTP 端口。

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

for generating a KeyStore and TrustStore, follow the tutorial要生成 KeyStore 和 TrustStore,请按照教程进行操作


From Marvin Pinto 's answer,马文平托的回答,

The javax.net.ssl.SSLHandshakeException exception is usually thrown when the server you're trying to connect to does not have a valid certificate from an authorized CA.当您尝试连接的服务器没有来自授权 CA 的有效证书时,通常会抛出javax.net.ssl.SSLHandshakeException异常。

Put simply, the server you're attempting to connect to is most likely using a self-signed certificate and you have to accomodate for that in your Java code.简而言之,您尝试连接的服务器很可能使用自签名证书,您必须在 Java 代码中适应它。 This involves creating a custom KeyStore , etc. See this Stack Overflow answer for full implementation details. This involves creating a custom KeyStore等。有关完整的实现细节,请参阅堆栈溢出答案。

If you want to clarify your conception completely, then read the tutorial which is for use of SSL with JavaMail .如果您想完全阐明您的概念,请阅读有关在 JavaMail 中使用 SSL教程

Related Link:相关链接:

  1. JAVAMAIL API FAQ JAVAMAIL API 常见问题
  2. Received fatal alert: handshake_failure through SSLHandshakeException 通过 SSLHandshakeException 收到致命警报:handshake_failure

You can use openssl to test the certificate and that way you can troubleshoot the handshake failure.您可以使用 openssl 来测试证书,这样您就可以解决握手失败的问题。

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

When I did it to that host you mention, I actually got:当我对你提到的那个主持人做这件事时,我实际上得到了:

Verify return code: 20 (unable to get local issuer certificate)验证返回码:20(无法获取本地颁发者证书)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM