微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 javax.mail 遵守 RHEL8 加密策略?

如何解决如何使用 javax.mail 遵守 RHEL8 加密策略?

我正在尝试使用 javax.mail 制作一个发送邮件的应用程序。

我一直在想如何解决错误 No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

我将在不控制操作系统的系统上使用它,因此我需要遵守认的 rhel8 策略。

  • 这适用于 Windows 10 机器。
  • 只有在我使用以下命令时,它才能在我的 rhel8 测试系统中工作:update-crypto-policies --set LEGACY

我需要在代码解决这个问题,而不是在操作系统中。

我在rhel8上遇到的错误

DEBUG SMTP: Found extension "CHUNKING",arg ""
DEBUG SMTP: Found extension "SMTPUTF8",arg ""
STARTTLS
220 2.0.0 SMTP server ready
EHLO localhost.localdomain
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)
    at javax.mail.Service.connect(Service.java:156)
    at javax.mail.Service.connect(Service.java:105)
    at javax.mail.Transport.send0(Transport.java:168)
    at javax.mail.Transport.send(Transport.java:98)
    at MailTest.sendMail(MailTest.java:59)
    at MailTest.main(MailTest.java:103)
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
    at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171)
    at sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:98)
    at sun.security.ssl.TransportContext.kickstart(TransportContext.java:220)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:428)
    at sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:804)
    at sun.security.ssl.SSLSocketImpl.access$200(SSLSocketImpl.java:73)
    at sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1166)
    at com.sun.mail.util.TraceOutputStream.write(TraceOutputStream.java:101)
    at java.io.bufferedoutputstream.flushBuffer(bufferedoutputstream.java:82)
    at java.io.bufferedoutputstream.flush(bufferedoutputstream.java:140)
    at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:1418)
    ... 10 more

我尝试过:

  • props.put("mail.smtp.ssl.protocols","TLSv1.2");
  • props.put("mail.smtp.ssl.protocols","TLSv1.3");
  • 没有 mail.smtp.ssl.protocols 条目

我的代码

import com.sun.mail.smtp.SMTPSendFailedException;
import java.io.IOException;
import java.util.Date;
import java.util.Properties;
import javax.mail.AuthenticationFailedException;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**
 * Standalone mail client.
 */
public class MailTest {
    
    private final Properties props;
    
    public MailTest(Properties props) {
        this.props = props;
    }
    
    public void sendMail() {
        try {
            Authenticator auth = null;
            final String username = props.getProperty("mail.username");
            final String password = props.getProperty("mail.password");
            if (username != null && username.length() > 0) {
                auth = new Authenticator() {
                    @Override
                    protected PasswordAuthentication getpasswordAuthentication() {
                        System.out.println("Providing authentication for: " + username);
                        return new PasswordAuthentication(username,password);
                    }
                };
            }
            
            Session session = Session.getInstance(props,auth);
            session.setDebug(true);
            
            MimeMessage msg = new MimeMessage(session);
            msg.addHeader("Content-type","text/HTML; charset=UTF-8");
            msg.addHeader("format","flowed");
            msg.addHeader("Content-transfer-encoding","8bit");

            msg.setFrom(new InternetAddress(props.getProperty("test.from"),"test"));
            msg.setReplyTo(InternetAddress.parse(props.getProperty("test.from"),false));
            msg.setSubject("Test","UTF-8");
            msg.setText("This is a test.","UTF-8");
            msg.setSentDate(new Date());

            msg.setRecipients(Message.RecipientType.TO,InternetAddress.parse(props.getProperty("test.to"),false));
            
            System.out.println("Sending message...");
            Transport.send(msg); 
            System.out.println("Message was sent.");
            
        } catch (AuthenticationFailedException ex) {
            System.err.println("Authentication Failed - please check the username and password.");
            ex.printstacktrace();
        } catch (SMTPSendFailedException ex) {
            System.err.println("SMTP error - please check your SMTP settings.");
            ex.printstacktrace();            
        } catch (MessagingException ex) {
            ex.printstacktrace();
        } catch (IOException ex) {
            ex.printstacktrace();
        }        
    }
    
    public static void main(String[] args) {
        System.out.println("Performing mail test.");

        Properties props = new Properties();

        // SMTP server and port
        props.put("mail.smtp.host","smtp.office365.com");
        props.put("mail.smtp.port","587");        

        // If set to false,username + password will not be used
        props.put("mail.smtp.auth","true");
        props.put("mail.username","test@example.com");
        props.put("mail.password","yourpassword");

        // If true,enables the use of the STARTTLS command (if supported by the server) 
        // to switch the connection to a TLS-protected connection before issuing any login commands. 
        // Defaults to false.
        props.put("mail.smtp.starttls.enable","true");
        props.put("mail.smtp.ssl.protocols","TLSv1.3");
        // If true,requires the use of the STARTTLS command. If the server doesn't support the STARTTLS command,// or the command fails,the connect method will fail. Defaults to false.
        props.put("mail.smtp.starttls.required","true");

        // FROM / TO address
        props.put("test.from","test@example.com");
        props.put("test.to","test@example.com");
        
        MailTest test = new MailTest(props);
        test.sendMail();
    }    
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。