You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java1.7遗留Web应用Office365 SMTP邮件发送SSL握手异常求助

Java 1.7 + Tomcat 7 连接Office365 SMTP发送带附件邮件时SSL握手失败问题

错误信息

javax.mail.MessagingException: Can't send command to SMTP host;
nested exception is:
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:1420)
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:1408)
at com.sun.mail.smtp.SMTPTransport.ehlo(SMTPTransport.java:847)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:384)
at javax.mail.Service.connect(Service.java:297)

环境与核心代码

我们有一个基于Java 1.7、mail1.4.jar构建并部署在Tomcat 7上的遗留Web应用,向Office365的SMTP发送带附件邮件时触发上述错误。配置从属性文件读取,核心代码片段如下:

final String username = ConfReader.getPropertyValue("mail.username");
final String passwd = ConfReader.getPropertyValue("mail.password");
from = ConfReader.getPropertyValue("mail.from");
String port = ConfReader.getPropertyValue("mail.port"); 

Properties props = new Properties();
props.put("mail.smtp.host", ConfReader.getPropertyValue("mail.smtp.host"));
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", port);
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.debug", "true");

Session session = Session.getInstance(props, new Authenticator() {
    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        LogWriter.logErrorMessage("username :: "
                + username + "passwd :: "+passwd);
        return new PasswordAuthentication(username, passwd);
    }
});

Message message = new MimeMessage(session);
try
{
    message.setFrom(new InternetAddress(from));

    final InternetAddress[] toAddress =
       InternetAddress.parse(toEmails);

    final InternetAddress[] ccAddress =
       InternetAddress.parse(ccEmails);
    
    message.setRecipients(Message.RecipientType.TO, toAddress);
    message.setRecipients(Message.RecipientType.CC, ccAddress);
    message.setSubject(subject);
    
    /*
     * Multipart to create the mail content.
     */
    final Multipart multipart = new MimeMultipart();
    /*
     * html body part to set in multipart
     */
    
    final MimeBodyPart htmlBodyPart = new MimeBodyPart();
    htmlBodyPart.setContent(htmlBody, "text/html");
    multipart.addBodyPart(htmlBodyPart);

    /*
     * source to read attachment content
     */
    DataSource source =
       new ByteArrayDataSource(bytes, "application/excel");
    /*
     * MimeBodyPart to hold the attachment content.
     */
    MimeBodyPart attachmentBodyPart = new MimeBodyPart();
    DataHandler handler = new DataHandler(source);
    attachmentBodyPart.setHeader("Content-Disposition",
       "attachment;filename=" + attachmentName);
    attachmentBodyPart.setDataHandler(handler);
    attachmentBodyPart.setFileName(attachmentName);
    multipart.addBodyPart(attachmentBodyPart);

    message.setContent(multipart);
    /*
     * following line to send email, if it fails, corresponding catch
     * block executes, which is logged to let know user if any error
     */
    
    Transport.send(message);
    
}
catch (AddressException e)
{
    /*
     * email sending failed, logging the information
     */
    
    LogWriter
       .logErrorMessage("Address Exception : " + e.getMessage());
    
}
catch (MessagingException e)
{
    /*
     * email sending failed, logging the information
     */
    
    LogWriter.logErrorMessage("Messaging Exception : "
       + e.getMessage());
}

已尝试的方案

  • 更新mail.jar至1.4.7版本
  • 代码中添加mail.smtp.starttls.enable=true和mail.debug=true属性
  • 删除部署服务器JRE的java.security文件中jdk.tls.disabledAlgorithms配置项
  • 切换SMTP端口至25并保持mail.smtp.starttls.enable=true
  • 代码中添加mail.smtp.ssl.protocols=TLSv1.2和mail.smtps.ssl.protocols=TLSv1.2属性

可行解决方案

1. 强制JVM启用TLSv1.2协议

Java 1.7默认不优先启用TLSv1.2,可通过JVM启动参数强制指定:

-Dhttps.protocols=TLSv1.2 -Djdk.tls.client.protocols=TLSv1.2

在Tomcat的catalina.sh(Linux)或catalina.bat(Windows)中添加上述参数,确保JVM在SSL握手时只使用TLSv1.2。

2. 升级JavaMail至兼容版本

建议直接升级到JavaMail 1.5.6及以上版本,这些版本对TLSv1.2的支持更完善,修复了老版本中的协议协商问题。替换时需移除旧的mail.jar,避免依赖冲突。

3. 解除JRE加密强度限制

Java 1.7默认存在加密强度限制,无法使用Office365要求的强加密套件。需下载对应JRE版本的无限强度策略文件,替换JRE/lib/security目录下的local_policy.jar和US_export_policy.jar。

4. 补充SMTP连接属性

在现有Properties配置中添加以下属性,明确指定SSL套接字工厂和协议:

props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
props.put("mail.smtp.ssl.enable", "true");

同时确认mail.smtp.host配置为正确的Office365地址:smtp.office365.com。

5. 验证服务器网络连通性

确保部署Tomcat的服务器能访问Office365的SMTP端口(587或25),可通过命令测试:

telnet smtp.office365.com 587

若网络不通,需检查防火墙或安全组规则,放行对应端口的出站流量。

内容的提问来源于stack exchange,提问作者Nageswara Rao P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 19:05:20