【问题标题】:Available ciphers web application可用的密码 Web 应用程序
【发布时间】:2018-07-10 20:06:22
【问题描述】:

此 java 应用程序需要使用 SMTP 和 TLS 发送电子邮件。

邮件发送代码在独立 java 应用程序 (java MailClient) 和我们之前的环境中执行时工作正常,但在 Tomcat 8 环境中执行时失败(Tomcat 8 AWS Beanstalk,OpenJDK 64-Bit Server VM(build 25.171- b10,混合模式))。

相关邮件发送代码(使用javax 1.6.1):

Properties props = new Properties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.host", smtpServerProperties.get(HOST_PROPERTY));
props.put("mail.smtp.port", smtpServerProperties.get(PORT_PROPERTY));
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
Authenticator auth = new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(smtpServerProperties.get(TLS_USER_PROPERTY), smtpServerProperties.get(TLS_PASSWORD_PROPERTY));
    }
};
Session session = Session.getInstance(props, auth);
MimeMessage email = createEmail(session, smtpSender, recipients, subject, content);
Transport transport = session.getTransport();
transport.connect(smtpServerProperties.get(HOST_PROPERTY),smtpServerProperties.get(TLS_USER_PROPERTY), smtpServerProperties.get(TLS_PASSWORD_PROPERTY) );
transport.sendMessage(email, email.getAllRecipients());

我得到的错误:

Caused by: java.io.EOFException: SSL peer shut down incorrectly
    at sun.security.ssl.InputRecord.read(InputRecord.java:505)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
    ... 13 more

我怀疑问题在于,在运行“内部”tomcat 时,应用程序的可用密码以某种方式受到限制,然后它就失败了。在 SSL 日志中,我可以看到应用程序之间的“不支持的密码套件”列表以及用于握手的初始 TLS 版本非常不同:

tomcat 内部:

Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_GCM_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
%% No cached client session
*** ClientHello, TLSv1

外面:

Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
%% No cached client session
*** ClientHello, TLSv1.2

编辑

在 Tomcat 中运行的同一个应用程序可以成功地与 mongoDb 服务器 (mongo-java-driver-3.2.2) 以及使用 https(标准 HttpURLConnection)的其他 Web 应用程序通信,并且在这两种情况下 ClientHello 都使用 TLSv1.2 .

问题是:tomcat 环境如何限制/更改 javax.mail 的可用密码,即使它(确实似乎是) 使用相同的 java 环境?

【问题讨论】:

  • 注意到您的客户说 TLSv1 与 TLSv1.2,stackoverflow.com/questions/28908835/…
  • 你确定它使用的是同一个Java环境吗?对我来说似乎是一个不同的人。 Tomcat 实际上根本不关心客户端 SSL 密码套件或 SSL 客户端。
  • “内部”的“不支持”密码的较长列表都是需要 TLS1.2 的套件,并且不能在它用作 @Compass 注释(或 1.1)的 1.0 中使用。这与使用 Java 7 一致,默认 1.2 和 1.1 用于 JSSE 服务器但客户端关闭,但 25.171 应该是 Java 8。此外,这两个列表显然都排除了与 Oracle/Sun Java 一致的所有 AES256 套件,直到最近没有添加了“无限强度”政策(您可以在此搜索许多其他问题),但 通常 不适用于 OpenJDK。 (也许亚马逊添加了它?)
  • 刚刚检查过,即使实例也安装了 openjdk 7,它也没有被使用。我百胜卸载它并手动删除了文件夹,但仍然有同样的错误。再三考虑,我认为这不仅仅是密码问题,因为同一个应用程序可以成功地与 mongo 服务器(TLSv1.2)和其他应用程序(使用 https 和 TLSv1.2 显示)通信。将更新问题
  • 正如其他人所建议的,这很可能是由于使用了不同的 JDK 版本及其不同的 SSL 默认值。请注意,您可以通过设置 mail.smtp.ssl.protocolsmail.smtp.ssl.ciphersuites 属性来覆盖 JavaMail 的默认值

标签: java ssl jakarta-mail tomcat8 starttls


【解决方案1】:

当然可以是密码。这绝对是因为您的 SSL 握手失败,但有很多原因会导致这种情况发生。

因为在应用程序托管在 Tomcat 中之前您没有看到该问题,这表明您可能正在处理 SSL 信任库问题。获取 SMTP 服务器的 SSL 端点提供的 SSL 证书,并使用 (java/bin) 密钥工具将该证书导入 Tomcat 的受信任密钥库。如果它已经在那里,您会收到一条消息,类似于“它已经在这里,您要重新导入它吗?”

重新导入它不会有什么坏处,但信任库通常不会动态加载,因此在您执行信任库导入后,您应该重新启动 Tomcat。您可以键入不带参数的 (java/bin) keytool 来获取帮助屏幕,但导入命令如下所示:

keytool -import -file smtpcert.cer -keystore -tomcattrust

您的文件名 (.cer) 和信任库名称可能与上述不同,如果提示输入密码,我认为默认密码是 changeit。

机会来了!

【讨论】:

  • 对服务器证书缺乏信任会导致ValidatorException,永远不会“对等方错误关闭”,所以这不是问题。如果是这样,信任叶证书通常是错误的解决方案。
  • 正如@dave_thompson_085 指出的那样,缺乏信任会导致其他错误,并且在握手的后期阶段(在不同场景中已经有一些错误)
【解决方案2】:

tldr:完整的 Web 应用程序有一个依赖项,包括旧版本的邮件类 (1.4),但它不起作用。修复是在 pom.file 中添加排除项:

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-multipart-provider</artifactId>
    <version>2.2.1.GA</version>
    <exclusions>
        <exclusion>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
        </exclusion>
    </exclusions>
</dependency>

解决这个问题的时间比预期的要长:

  • 同一个 Web 应用程序在(完全)不同的环境中工作 - windows server、Sun JDK8、Tomcat7
  • 电子邮件发送类位于“核心”项目中,不包含任何其他邮件依赖项
  • 最初的怀疑是在“内部”和“外部”版本中使用了不同的类/实现,但它们是“相同的”(至少是名称)

用于查找的步骤:

使用以下标志执行 java 应用程序:

-verbose:class
-verbose:jni

并检查日志:

  • 独立应用程序(在运行我的“主”类时,我使用了网络部署中的库):[Loaded com.sun.mail.smtp.SMTPTransport from file:/var/lib/tomcat8/webapps/myapp/WEB-INF/lib/javax.mail-1.6.1.jar]
  • 网络应用程序:[Loaded com.sun.mail.smtp.SMTPTransport from file:/var/lib/tomcat8/webapps/myapp/WEB-INF/lib/mail-1.4.jar]

基于运行 mvn 依赖 mvn dependency:tree 并查看两个邮件依赖的最终验证:

[INFO] +- com.my.company:my-core:jar:1.70:compile
[INFO] |  \- com.sun.mail:javax.mail:jar:1.6.1:compile
...
[INFO] +- org.jboss.resteasy:resteasy-multipart-provider:jar:2.2.1.GA:compile
[INFO] |  +- javax.mail:mail:jar:1.4:compile

【讨论】:

    猜你喜欢
    • 2011-09-21
    • 1970-01-01
    • 2016-01-04
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 2018-01-05
    • 2016-06-23
    • 1970-01-01
    相关资源
    最近更新 更多