尝试通过JavaMail连接到Gmail时出现SSL握手错误

问题描述:

尝试使用JavaMail库通过POP3从Gmail接收邮件并输出,但发生SSL握手错误。你如何使SSL握手发生?尝试通过JavaMail连接到Gmail时出现SSL握手错误

任何帮助,将不胜感激

代码:

import java.util.Properties; 
import javax.mail.Folder; 
import javax.mail.Message; 
import javax.mail.MessagingException; 
import javax.mail.NoSuchProviderException; 
import javax.mail.Session; 
import javax.mail.Store; 

public class CheckingMails { 

public static void check(String host, String storeType, String user, 
    String password) 
{ 
    try { 


    Properties properties = new Properties(); 

    properties.put("mail.pop3.host", host); 
    properties.put("mail.pop3.port", "995"); 
    properties.put("mail.pop3.starttls.enable", "true"); 
    Session emailSession = Session.getDefaultInstance(properties); 


    Store store = emailSession.getStore("pop3s"); 

    store.connect(host, user, password); 


    Folder emailFolder = store.getFolder("INBOX"); 
    emailFolder.open(Folder.READ_ONLY); 


    Message[] messages = emailFolder.getMessages(); 
    System.out.println("messages.length---" + messages.length); 

    for (int i = 0, n = messages.length; i < n; i++) { 
    Message message = messages[i]; 
    System.out.println("---------------------------------"); 
    System.out.println("Email Number " + (i + 1)); 
    System.out.println("Subject: " + message.getSubject()); 
    System.out.println("From: " + message.getFrom()[0]); 
    System.out.println("Text: " + message.getContent().toString()); 

    } 

    //close the store and folder objects 
    emailFolder.close(false); 
    store.close(); 

    } catch (NoSuchProviderException e) { 
    e.printStackTrace(); 
    } catch (MessagingException e) { 
    e.printStackTrace(); 
    } catch (Exception e) { 
    e.printStackTrace(); 
    }} public static void main(String[] args) { 

    String host = "pop.gmail.com"; 
    String mailStoreType = "pop3"; 
    String username = "[email protected]"; 
    String password = "xxx"; 

    check(host, mailStoreType, username, password);}} 

输出:

javax.mail.MessagingException: Connect failed; 
    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.pop3.POP3Store.protocolConnect(POP3Store.java:213) 
    at javax.mail.Service.connect(Service.java:366) 
    at javax.mail.Service.connect(Service.java:246) 
    at reademail.CheckingMails.check(CheckingMails.java:30) 
    at reademail.CheckingMails.main(CheckingMails.java:70) 
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 sun.security.ssl.Alerts.getSSLException(Alerts.java:192) 
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1937) 
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) 
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) 
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1478) 
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:212) 
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979) 
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:914) 
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1050) 
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1363) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1391) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1375) 
    at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:598) 
    at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:372) 
    at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238) 
    at com.sun.mail.pop3.Protocol.<init>(Protocol.java:112) 
    at com.sun.mail.pop3.POP3Store.getPort(POP3Store.java:265) 
    at com.sun.mail.pop3.POP3Store.protocolConnect(POP3Store.java:207) 
    ... 4 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:387) 
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) 
    at sun.security.validator.Validator.validate(Validator.java:260) 
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) 
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) 
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) 
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1460) 
    ... 17 more 
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
    at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:145) 
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:131) 
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) 
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382) 
    ... 23 more 
+0

您的信任库不信任其证书。您是否使用自定义信任库? Java附带的应该相信它。 – EJP

+1

请参阅[此JavaMail FAQ条目](http://www.oracle.com/technetwork/java/javamail/faq/index.html#installcert)中的常见原因。 –

如果任何人有这个问题绊倒以后,像我一样,解决的办法是:

properties.put("mail.pop3.host", host); 
properties.put("mail.pop3.port", "995"); 
properties.put("mail.pop3.starttls.enable", "true"); 
props.put("mail.pop3s.ssl.trust", host); // add this line 
Session emailSession = Session.getDefaultInstance(properties); 

您可以添加第四行以信任您尝试连接的主机。永远不要用主机参数代替“*”

得到这个问题的周围其他方式添加SSL证书到Java cacerts的

要做到这一点,你必须:

  1. 使用Firefox,导出 “.CRT”通过点击地址栏上的绿色挂锁,可以从页面(例如gmail.com)获得文件。
  2. 在Windows中,使用管理员权限打开CMD。
  3. 执行以下(例如,为谷歌Gmail证书)

    keytool -import -trustcacerts -alias googlemail -file mailgooglecom.crt -noprompt -keystore cacerts

完成。