【问题标题】:Unable to Send Mail - javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?无法发送邮件 - javax.net.ssl.SSLException:无法识别的 SSL 消息,明文连接?
【发布时间】:2016-08-04 02:07:33
【问题描述】:

我们使用 Spring JavaMailSenderImpl 发送邮件。以下是配置

 <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="${host}"/>
        <property name="port" value="${port}"/>
        <property name="username" value="${mail.username}"/>
        <property name="password" value="${mail.password}"/>
        <property name="javaMailProperties">
            <props>
                <!-- Use SMTP transport protocol -->
                <prop key="mail.transport.protocol" >${mail.transport.protocol}</prop>
                <!-- Use SMTP-AUTH to authenticate to SMTP server -->
                <prop key="mail.smtp.auth">${mail.smtp.auth}</prop>
                <!-- Use TLS to encrypt communication with SMTP server -->
                <prop key="mail.smtp.starttls.enable">${mail.smtp.starttls.enable}</prop>
                <prop key="mail.debug">false</prop>
                <prop key="mail.smtp.ssl.enable">true</prop>
            </props>
        </property>
    </bean>

属性文件:-

host=XXXX.XXXX.XX
port=25
mail.username=xxxxxxxx
mail.password=xxxxxxx
mail.transport.protocol=smtp
mail.smtp.auth=true
mail.smtp.starttls.enable=true

控制台日志

Exception in thread "taskExecutor-2" org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not connect to SMTP host: XXXX.XXXX.XX, port: 25;
      nested exception is:
            javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?. Failed messages: javax.mail.MessagingException: Could not connect to SMTP host: XXXX.XXXX.XX, port: 25;
      nested exception is:
            javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?; message exception details (1) are:
    Failed message 1:
    javax.mail.MessagingException: Could not connect to SMTP host: XXXX.XXXX.XX, port: 25;
      nested exception is:
            javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
            at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1934)
            at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:638)
            at javax.mail.Service.connect(Service.java:295)
            at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:389)
            at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:340)
            at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:336)
            at com.XXXX.Mailer$1.run(Mailer.java:52)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
            at java.lang.Thread.run(Thread.java:744)
    Caused by: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
            at sun.security.ssl.InputRecord.handleUnknownRecord(InputRecord.java:671)
            at sun.security.ssl.InputRecord.read(InputRecord.java:504)
            at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927)
            at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
            at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
            at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
            at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:507)
            at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238)
            at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1900)
            ... 9 more

我们确信这与 SSL 证书无关,因为在同一服务器中部署了其他 Web 应用程序,它们使用相同的配置完美地发送电子邮件。这可能是什么问题?

【问题讨论】:

  • 您确定配置正确吗? SMTP SSL 端口通常不是 25,更像是 465
  • 阳性。同一服务器中的不同应用程序具有相同的配置,可以发送电子邮件。
  • 我投票决定重新提出这个问题,因为链接的问题 stackoverflow.com/questions/6532273/… 讨论了 HTTPs 与 HTTP,而 NOT 像 OP 一样讨论了 SMTPS 与 SMTP
  • @StefanHaberl IMO 的根本原因可能类似——此错误并非特定于 HTTP/SMTP 协议,而是 HTTPS 和 SMTPS 共享的 SSL 协议。
  • @OctaviaTogami 是的,原因相同。但是,您必须为 HTTP 和 SMTP 设置不同的属性才能使其正常工作

标签: java spring ssl jakarta-mail


【解决方案1】:

问题出现在 javax.mail 1.4.0 中,升级到 1.4.7 解决了我的问题

【讨论】:

    【解决方案2】:

    我尝试了很多方法来解决这个问题,但最终我自己发现了这个问题。

    1. 在创建代码之前,请确保您能够从终端或任何其他邮件客户端发送电子邮件。一旦您测试邮件工作正常,然后使用以下属性和代码。我已经在电子邮件服务器中部署了代码,所以我不需要 SSL 或 TLS。我正在使用端口 25 进行中继。

    2. 必需的属性 -

      mail.smtp.host=<myhostname.com>
      mail.smtp.port=25
      mail.smtp.auth=true
      mail.transport.protocol=smtp
      smtpd_recipient_restrictions=permit_sasl_authenticated
      user=<sender_username/email>
      password=<password>
      mail.smtp.username=<sender_username/email>
      mail.smtp.password=<password>
      
    3. 所需代码 -

      public String sendEmail(String email){
      
               //Compose the message  
                try {  
      
                      FileReader reader=new FileReader("smtp.properties");  
                   //Get the session object  
                      Properties props = new Properties(); 
                      props.load(reader); 
      
                      System.out.println(" Props :: " + props.toString());
                      String to = email;
                      String host=props.getProperty("mail.smtp.host");
                      final String user=props.getProperty("user");
                      final String password=props.getProperty("password");
      
                     Session session = Session.getInstance(props,
                      new javax.mail.Authenticator() {
                          protected PasswordAuthentication getPasswordAuthentication() {
                              return new PasswordAuthentication(user, password);
                          }
                      }); 
      
                      Message message = new MimeMessage(session);
                      message.setFrom(new InternetAddress(user));
                      message.setRecipients(
                              Message.RecipientType.TO,
                              InternetAddress.parse(to)
                      );
      
                      message.setSubject("Testing - SMTP");
                      message.setText("Dear User, \n\n Hello !");
      
                      Transport.send(message);
      
                      System.out.println("Done");
      
                     } catch (MessagingException e) {
                          e.printStackTrace();
                     } catch (IOException ex) {  
                          ex.printStackTrace();
                     }
                return "SUCCESS";
           }
      
    4. 必需的进口 -

      import javax.mail.*;
      import javax.mail.internet.InternetAddress;
      import javax.mail.internet.MimeMessage;
      import java.util.Properties;
      

    【讨论】:

      【解决方案3】:
      <prop key="mail.smtp.starttls.enable">${mail.smtp.starttls.enable}</prop>
      <prop key="mail.smtp.ssl.enable">true</prop>
      

      您需要mail.smtp.ssl.enable 在 TCP 连接(端口 465)之后直接用于隐式 SSL,或者使用 STARTTLS 命令(端口 25)使用mail.smtp.starttls.enable 用于显式 SSL。但是使用您当前的属性,您将两者都设置为 true。

      这意味着它将建立一个 TCP 连接到端口 25 并在那里尝试 SSL 握手。这将失败,因为服务器从 SMTP 对话框发送纯文本问候语,而不是预期的 SSL 握手。这样你就得到了

      无法识别的 SSL 消息,明文连接?

      要修复它,请确保您使用隐式或显式 SSL,但不能同时使用取决于端口,即端口 25 mail.smtp.ssl.enable 应该为 false。

      【讨论】:

      • 我会试试这个。但令人困惑的是,我们已经在同一个 tomcat 服务器的不同应用程序中启用了两者,并且邮件工作正常。这里有什么可以使其特定于 tomcat 中部署的应用程序吗?
      • @ArunM:我的猜测是,如果隐式 TLS 已经完成,它不会尝试显式 TLS (STARTTLS),因为在 TLS 中执行 TLS 没有意义。这意味着如果mail.smtp.ssl.enable 为真,mail.smtp.starttls.enable 将被隐式忽略,因此任何与端口 465 (smtps) 的连接都应该正常工作。
      猜你喜欢
      • 2011-06-06
      • 1970-01-01
      • 2014-08-08
      • 2016-08-28
      • 1970-01-01
      • 2014-02-04
      • 2011-09-25
      相关资源
      最近更新 更多