【问题标题】:Using Javamail and Greenmail for SMTPS/SSL将 Javamail 和 Greenmail 用于 SMTPS/SSL
【发布时间】:2011-09-27 00:37:16
【问题描述】:

我正在尝试编写一个测试,该测试将使用 JavaMail SMTP 或 SMTPS 通过 SSL 和身份验证向我正在运行的 Greenmail 服务器发送消息。

我写了一个快速的小子,应该完全符合我的要求:

import java.util.Properties;

import javax.mail.Session;
import javax.mail.Transport;

import com.icegreen.greenmail.user.GreenMailUser;
import com.icegreen.greenmail.util.GreenMail;

public class MailTest {
    public static void main(String[] args) throws Exception {
        GreenMail greenmail = new GreenMail();
        try {
            greenmail.start();

            String email = "foo@bar";
            String userid = "user";
            String password = "pa$$word";
            GreenMailUser setUser = greenmail.setUser(email, userid, password);
            setUser.create();
            GreenMailUser user = greenmail.getManagers().getUserManager().getUser(userid);
            System.out.println("User created:" + user.getEmail() + ":" + user.getLogin() + ":" + user.getPassword());

            int portSmtps = greenmail.getSmtps().getPort();
            System.out.println("Smtps started on port:" + portSmtps);

            Properties props = new Properties();
            props.put("mail.smtp.starttls.enable", "true");
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.host", "localhost");
            props.put("mail.smtp.socketFactory.port", portSmtps);
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.socketFactory.fallback", "false");
            Session session = Session.getInstance(props);
            Transport transport = session.getTransport("smtp");
            transport.connect("localhost", portSmtps, userid, password);
            System.out.println("Transport is connected: " + transport.isConnected());
        } finally {
            greenmail.stop();
        }
    }
}

我的问题是我遇到了几个例外:

Exception in thread "Thread-7" java.lang.RuntimeException: javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
    at com.icegreen.greenmail.smtp.SmtpHandler.run(Unknown Source)
Caused by: javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.java:1293)
    at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:65)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
    at java.io.InputStreamReader.read(InputStreamReader.java:167)
    at java.io.BufferedReader.fill(BufferedReader.java:136)
    at java.io.BufferedReader.readLine(BufferedReader.java:299)
    at java.io.BufferedReader.readLine(BufferedReader.java:362)
    at com.icegreen.greenmail.smtp.SmtpConnection.readLine(Unknown Source)
    at com.icegreen.greenmail.smtp.SmtpHandler.handleCommand(Unknown Source)
    ... 1 more
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1720)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:954)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:632)
    at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
    at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)
    at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)
    at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
    at java.io.BufferedWriter.flush(BufferedWriter.java:236)
    at java.io.PrintWriter.flush(PrintWriter.java:276)
    at com.icegreen.greenmail.util.InternetPrintWriter.println(Unknown Source)
    at com.icegreen.greenmail.util.InternetPrintWriter.println(Unknown Source)
    at com.icegreen.greenmail.smtp.SmtpConnection.println(Unknown Source)
    at com.icegreen.greenmail.smtp.SmtpHandler.sendGreetings(Unknown Source)
    ... 1 more
Exception in thread "main" javax.mail.MessagingException: Could not connect to SMTP host: localhost, port: 3465;
  nested exception is:
    javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    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 MailTest.main(MailTest.java:35)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
    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)
    ... 3 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
    at sun.security.validator.Validator.validate(Validator.java:218)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185)
    ... 13 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
    ... 19 more

我已经尝试在这里查看其他一些答案,但我一定遗漏了一些东西:

抱歉发了这么长的帖子,提前感谢您的任何建议。

【问题讨论】:

  • SSL 具有特定的信任模型,用于基于证书的身份验证。关于 SMTPS 服务器证书,您能告诉我们什么?也许它是自签名的?

标签: java ssl smtp jakarta-mail greenmail


【解决方案1】:

您应该像这样启动您的 GreenMail 服务器:

Security.setProperty("ssl.SocketFactory.provider", DummySSLSocketFactory.class.getName());
GreenMail mailServer = new GreenMail(ServerSetupTest.SMTPS);
mailServer.start();

【讨论】:

    【解决方案2】:

    Greenmail 服务器上使用的 SSL 证书必须由“已知”证书颁发机构签署,或者您必须将用于签署证书的 CA 证书添加到 Java 的密钥库中。没有办法告诉 Java 不验证证书链到一个已知的 CA。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-16
      • 2017-07-14
      • 1970-01-01
      • 2011-06-11
      • 2014-02-12
      • 1970-01-01
      • 2012-01-16
      相关资源
      最近更新 更多