0

如何配置我的 Java 应用程序以使用端口 993 和 TLS 从 IMAP 邮箱读取邮件。

我将邮件服务器的证书存储在默认的 javakeystore 中cacerts。尝试连接到邮箱后。我得到了这个堆栈跟踪(这是一个完整的跟踪):

 javax.mail.MessagingException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty;
 nested exception is:
    javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
    at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:670)
    at javax.mail.Service.connect(Service.java:317)
    at javax.mail.Service.connect(Service.java:176)
    at javax.mail.Service.connect(Service.java:125)
    at imap.IMAP.receive(IMAP.java:77)
    at imap.IMAP.main(IMAP.java:46)
 Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1764)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1725)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1708)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1237)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1214)
    at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:548)
    at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:352)
    at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:207)
    at com.sun.mail.iap.Protocol.<init>(Protocol.java:113)
    at com.sun.mail.imap.protocol.IMAPProtocol.<init>(IMAPProtocol.java:111)
    at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:637)
    ... 5 more
Caused by: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
    at sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:57)
    at sun.security.validator.Validator.getInstance(Validator.java:161)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:108)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:204)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185)
    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:958)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1203)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1230)
    ... 12 more
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
    at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:183)
    at java.security.cert.PKIXParameters.<init>(PKIXParameters.java:103)
    at java.security.cert.PKIXBuilderParameters.<init>(PKIXBuilderParameters.java:87)
    at sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:55)
    ... 23 more
15.03.2013 13:54:50 imap.IMAP main
SCHWERWIEGEND: null
java.lang.NullPointerException
    at imap.IMAP.receive(IMAP.java:123)
    at imap.IMAP.main(IMAP.java:46)

这是我的比例:

System.setProperty("javax.net.ssl.trustStore", "/usr/java/jdk_1.6.0_35/jre/lib/security/cacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

Properties props = System.getProperties();

props.setProperty("mail.imaps.host", server);
props.setProperty("mail.imaps.user", user);
props.setProperty("mail.imaps.password", password);
props.setProperty("mail.imaps.auth", "true");
props.setProperty("mail.imaps.starttls.enable", "true");
props.setProperty("mail.imaps.socketFactory.port", "993");
props.setProperty("mail.imaps.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.imaps.socketFactory.fallback", "false");

MailAuthenticator auth = new MailAuthenticator(user, password);

Session session = Session.getDefaultInstance(props, auth);

store = session.getStore("imaps");
store.connect();

有什么遗漏吗?在互联网上有很多关于这个问题的帖子。但大多数是用于 SMTP。我还没有找到真正解释的东西,你真的需要哪些属性才能让这个案例工作。

我希望有人可以帮助我找到我的错误。

非常感谢。

4

1 回答 1

1

首先是一些评论,这不是您的问题的原因,但会简化您的程序......

摆脱 socketFactory 属性,您不需要它们。

使用 Session.getInstance 而不是 Session.getDefaultInstance。

摆脱 MailAuthenticator 并调用 store.connect(user, password)。

有关详细信息,请参阅JavaMail 常见问题解答

至于您遇到的异常,这似乎是与您的证书或您的信任库有关的一些问题。 这个 JavaMail FAQ 条目提供了调试这类问题的提示。您可能需要 Java SSL/网络/安全专家来解释问题所在。

您说您已经将您的证书添加到您的信任库中,但以防万一您可能想查看此 JavaMail FAQ entry

于 2013-03-16T00:04:45.077 回答