这个 Jakarta Mail 代码到底加密了什么,为什么收到的电子邮件被标记为未验证?

What exactly is encrypted with this Jakarta Mail code, and why is the received email marked as unverified?

我正在使用 Jakarta Mail 和我的电子邮件提供商 (hover) smtp 服务器发送电子邮件。我预计必须安装 smtp 服务器 public 密钥,并将其与请求一起传递以加密流量。然而,它似乎没有那个工作。 This SO answer () 似乎表明这可能不是必需的,因为悬停将使用由商业证书颁发机构签署的证书。此外,调试打印输出似乎表明使用了 ssl。

我有两个问题。第一个是下面的代码究竟加密了什么:登录名、电子邮件、两者或两者都不加密。

代码如下:

        // to and from addresses
        String to = "myemail@gmail.com";
        String from = "myemail@mycompany.com";

        final String password = "mypassword";

        String host = "mail.hover.com";
        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");

        props.put("mail.smtp.ssl.enable", "true");
        
        // works same with this commented or not
        // props.put("mail.smtp.ssl.trust", "mail.hover.com");

        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", "465");
        
        // print out debug messages
        props.put("mail.debug", "true");
        
        //create the Session object
        Session session = Session.getInstance(props, new Authenticator() {
            
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(to, password);
            }
            
        });
        
        
        try {
            //create a MimeMessage object

            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
            message.setSubject("Here comes Jakarta Mail!");
            message.setContent("Just discovered that Jakarta Mail is fun and easy to use", "text/html");

            //send the email message
             Transport.send(message);
            
            // this works too
            // Transport transport = session.getTransport("smtps");
            // transport.connect("mail.hover.com", 465, username, password);
            // transport.sendMessage(message, message.getAllRecipients());

            System.out.println("Email Message Sent Successfully");

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    

    }

我的第二个问题是为什么 google 收到已发送的电子邮件时将其标记为未验证?我怀疑这与我的第一个问题有关。

这是我的调试打印输出:

DEBUG: Jakarta Mail version 2.0.0 DEBUG: successfully loaded resource: /META-INF/javamail.default.providers DEBUG: Tables of loaded providers DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPTransport=jakarta.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle], com.sun.mail.imap.IMAPSSLStore=jakarta.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], com.sun.mail.pop3.POP3Store=jakarta.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle], com.sun.mail.smtp.SMTPSSLTransport=jakarta.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], com.sun.mail.imap.IMAPStore=jakarta.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], com.sun.mail.pop3.POP3SSLStore=jakarta.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle]} DEBUG: Providers Listed By Protocol: {imap=jakarta.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], smtp=jakarta.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle], pop3=jakarta.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle], imaps=jakarta.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], smtps=jakarta.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], pop3s=jakarta.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle]} DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map DEBUG: getProvider() returning jakarta.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle] DEBUG SMTP: need username and password for authentication DEBUG SMTP: protocolConnect returning false, host=mail.hover.com, user=paul, password= DEBUG SMTP: useEhlo true, useAuth true DEBUG SMTP: trying to connect to host "mail.hover.com", port 465, isSSL true 220 smtp.hostedemail.com ESMTP DEBUG SMTP: connected to host "mail.hover.com", port: 465 EHLO 192.168.0.12 250-omf04.hostedemail.com 250-PIPELINING 250-SIZE 36700160 250-ETRN 250-AUTH PLAIN LOGIN 250-AUTH=PLAIN LOGIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250-DSN 250 CHUNKING DEBUG SMTP: Found extension "PIPELINING", arg "" DEBUG SMTP: Found extension "SIZE", arg "36700160" DEBUG SMTP: Found extension "ETRN", arg "" DEBUG SMTP: Found extension "AUTH", arg "PLAIN LOGIN" DEBUG SMTP: Found extension "AUTH=PLAIN", arg "LOGIN" DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg "" DEBUG SMTP: Found extension "8BITMIME", arg "" DEBUG SMTP: Found extension "DSN", arg "" DEBUG SMTP: Found extension "CHUNKING", arg "" DEBUG SMTP: protocolConnect login, host=mail.hover.com, user=myemail@mybusiness.ca, password= DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2 DEBUG SMTP: Using mechanism LOGIN DEBUG SMTP: AUTH LOGIN command trace suppressed DEBUG SMTP: AUTH LOGIN succeeded DEBUG SMTP: use8bit false MAIL FROM:myemail@mybusiness.ca 250 2.1.0 Ok RCPT TO:myemail@gmail.com 250 2.1.5 Ok DEBUG SMTP: Verified Addresses DEBUG SMTP: myemail@gmail.com DATA 354 End data with . Date: Tue, 9 Feb 2021 10:31:07 -0500 (EST) From: myemail@mybusiness.ca To: myemail@gmail.com Message-ID: <1880587495.0.1612884672084@[192.168.0.11]> Subject: Here comes Jakarta Mail! MIME-Version: 1.0 Content-Type: text/html; charset=us-ascii Content-Transfer-Encoding: 7bit Just discovered that Jakarta Mail is fun and easy to use 250 Ok Queued as books05_4e0c9e627608 DEBUG SMTP: message successfully delivered to mail server QUIT 221 2.0.0 Bye Email Message Sent Successfully

提前致谢!

首先我要感谢@Robert,他在他的评论中回答了我的第一个问题,在他对我的第二个问题的评论中他提到了 DKIM,这让我走上了解决我的第二个问题的道路。

所以我第一个问题的答案是雅加达邮件示例中的所有内容都已加密,包括登录名和消息。您不需要使用 smpt 服务器 public 密钥,因为在我的例子中它使用由商业证书颁发机构签名的证书。 (根据@Robert 和 )

关于我的第二个问题,为什么goole在收到我的电子邮件时将其标记为未验证,答案是在发送电子邮件时使用DKIM对电子邮件进行签名。为此,我遵循了以下步骤:

为了签署我的电子邮件,我使用了这个库:https://github.com/markenwerk/java-utils-mail-dkim。注意我不得不恢复使用来自 jakarta 邮件的 javax 邮件,因为库中的这个方法需要 javax.mail.internet.MimeMessage DkimMessage(mimeMessage, dkimSigner);

然后我使用此工具生成私钥和 public 密钥:https://tools.socketlabs.com/dkim/generator 将私钥粘贴到一个文件中,并以 .pem 扩展名命名。

现在您必须将 DKIM TXT 记录添加到您网站的 DNS 设置中。这是一个 link 解释如何:https://blog.mailtrap.io/create-dkim-tutorial/

库需要 .der 文件,因此使用 openssl 将 .pem 转换为 .der,命令如下: openssl pkcs8 -topk8 -nocrypt -in myDkim.pem -out myDkim.der -outform der

然后我使用以下方法对我的电子邮件进行签名,该方法改编自图书馆网页上的说明。

private DkimMessage dkimSignMessage(MimeMessage message, String from, String signingDomain, String selector, File derFile) {    
    try {
        DkimSigner dkimSigner = new DkimSigner(signingDomain, selector, derFile);
        dkimSigner.setIdentity(from);
        dkimSigner.setHeaderCanonicalization(Canonicalization.SIMPLE);
        dkimSigner.setBodyCanonicalization(Canonicalization.RELAXED);
        dkimSigner.setSigningAlgorithm(SigningAlgorithm.SHA256_WITH_RSA);
        dkimSigner.setLengthParam(true);
        dkimSigner.setCopyHeaderFields(false);
        return new DkimMessage(message, dkimSigner);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

完成这些步骤后,google 不再将电子邮件标记为未验证。这是一个 link,对 DKIM 有很好的解释:https://postmarkapp.com/guides/dkim