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

无法通过公司服务器发送SSL邮件,遇SSL异常寻求技术协助

解决Java邮件发送的SSL异常:Unrecognized SSL message, plaintext connection?

嘿,我来帮你搞定这个邮件发送的SSL问题~这个错误的核心原因很明确:你正在尝试用SSL直接连接一个初始是明文的端口,导致SSL握手时无法识别服务器返回的明文响应,所以抛出了这个异常。

问题出在你的配置冲突

看你的代码,你用了smtps协议(直接SSL连接),但指定的端口是587——而587是标准的STARTTLS端口,这个端口一开始是明文连接,需要先建立普通连接,再通过STARTTLS命令升级为SSL加密。你直接用SSL握手去连它,服务器返回的是明文的SMTP问候,SSL层自然认不出来。

另外你还同时配置了mail.smtps.socketFactory.class,强制使用SSL Socket连接,这就和587端口的工作方式彻底冲突了。

两种修复方案,选适合你的一种

方案一:使用STARTTLS(推荐,符合587端口的标准用法)

把代码改成普通SMTP协议+STARTTLS升级的模式,具体修改点如下:

public static void Send(final String username, final String password, String recipientEmail, String ccEmail, String title, String message) throws AddressException, MessagingException {
    System.setProperty("java.net.useSystemProxies", "true");
    // Java 8及以上无需手动添加SSL Provider,默认已包含,注释掉这行
    // Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

    Properties props = System.getProperties();
    // 切换为smtp协议,启用STARTTLS
    props.setProperty("mail.smtp.starttls.enable", "true");
    props.setProperty("mail.smtp.host", "mail.company.au");
    props.setProperty("mail.smtp.user", username);
    props.setProperty("mail.smtp.password", password);
    props.setProperty("mail.smtp.port", "587");
    props.setProperty("mail.smtp.auth", "true");
    // 移除强制SSL Socket的配置,STARTTLS会自动升级连接
    props.setProperty("mail.smtp.timeout", "5000");
    props.setProperty("mail.smtp.connectiontimeout", "5000");
    props.setProperty("mail.smtp.writetimeout", "5000");

    Session session = Session.getInstance(props, null);
    session.setDebug(true);
    MimeMessage msg = new MimeMessage(session);

    msg.setFrom(new InternetAddress(username));
    msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipientEmail, false));
    // 增加null判断,避免空指针异常
    if (ccEmail != null && ccEmail.length() > 0) {
        msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(ccEmail, false));
    }
    msg.setSubject(title);
    msg.setText(message, "utf-8");
    msg.setSentDate(new Date());

    // 使用smtp协议获取Transport
    SMTPTransport t = (SMTPTransport) session.getTransport("smtp");
    t.connect("mail.company.au", username, password);
    t.sendMessage(msg, msg.getAllRecipients());
    t.close();
}

修改说明:

  • 把所有mail.smtps.*属性改成mail.smtp.*,协议也从smtps切换为smtp
  • 删除了mail.smtps.socketFactory.class配置,STARTTLS会自动完成从明文到SSL的升级
  • 增加了ccEmail的null判断,防止空指针异常
  • 注释掉了手动添加SSL Provider的代码,Java 8及以上版本默认已经包含该Provider,无需手动添加

方案二:使用直接SSL连接(465端口)

如果你的公司邮件服务器支持465端口的直接SSL连接,可以这样修改:

public static void Send(final String username, final String password, String recipientEmail, String ccEmail, String title, String message) throws AddressException, MessagingException {
    System.setProperty("java.net.useSystemProxies", "true");
    // Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

    Properties props = System.getProperties();
    // smtps协议默认是直接SSL连接,无需STARTTLS
    props.setProperty("mail.smtps.host", "mail.company.au");
    props.setProperty("mail.smtps.user", username);
    props.setProperty("mail.smtps.password", password);
    // 切换为465端口
    props.setProperty("mail.smtps.port", "465");
    props.setProperty("mail.smtps.auth", "true");
    props.setProperty("mail.smtps.timeout", "5000");
    props.setProperty("mail.smtps.connectiontimeout", "5000");
    props.setProperty("mail.smtps.writetimeout", "5000");

    Session session = Session.getInstance(props, null);
    session.setDebug(true);
    MimeMessage msg = new MimeMessage(session);

    msg.setFrom(new InternetAddress(username));
    msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipientEmail, false));
    if (ccEmail != null && ccEmail.length() > 0) {
        msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(ccEmail, false));
    }
    msg.setSubject(title);
    msg.setText(message, "utf-8");
    msg.setSentDate(new Date());

    SMTPTransport t = (SMTPTransport) session.getTransport("smtps");
    t.connect("mail.company.au", username, password);
    t.sendMessage(msg, msg.getAllRecipients());
    t.close();
}

修改说明:

  • 保留smtps协议和属性前缀
  • 把端口改成465
  • 移除了mail.smtps.starttls.enable和mail.smtps.socketFactory.class配置(smtps协议默认已经使用SSL连接,无需额外配置)

额外验证步骤

可以先用命令行测试一下服务器端口的支持情况:

  • 测试587端口:telnet mail.company.au 587,输入EHLO localhost,看返回内容里有没有STARTTLS字样,有就说明支持STARTTLS
  • 测试465端口:openssl s_client -connect mail.company.au:465,如果能建立SSL连接,说明支持直接SSL

内容的提问来源于stack exchange,提问作者user9130545

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:50:07