无法发送邮件 - javax.net.ssl.SSLException:无法识别的 SSL 消息,纯文本连接?

Unable to Send Mail - javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?

我们正在使用 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.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 应用程序,它们使用相同的配置完美地发送电子邮件。这可能是什么问题?

<prop key="mail.smtp.starttls.enable">${mail.smtp.starttls.enable}</prop>
<prop key="mail.smtp.ssl.enable">true</prop>

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

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

Unrecognized SSL message, plaintext connection?

要修复此问题,请确保您使用隐式或显式 SSL,但不能同时使用这两种 SSL,具体取决于端口,即对于端口 25 mail.smtp.ssl.enable 应该为 false。

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

  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;
    

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