it-swarm.com.de

Fehler in JavaMail: Der PKIX-Pfad konnte keinen gültigen Zertifizierungspfad für das angeforderte Ziel finden

Ich versuche, eine E-Mail-Client-App in Android zu erstellen, und jetzt möchte ich den JavaMail-Teil konfigurieren.

ich versuche die Verbindung zum IMAP-Server herzustellen, aber mit meinem Code stimmt etwas nicht ... ... Hier ist mein Code:

package mailpackage;

import Java.util.Properties;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;

public class Connection implements Runnable
{
    boolean done;

    public Connection()
    {
        this.done=false;
    }

    @Override
    public void run()
    {
        System.out.println("Hello from Connection Thread!");
        while(!done)
        {
            String Host = "myhost";// change accordingly
            String mailStoreType = "imap";
            String username = "myusername";// change accordingly
            String password = "mypasswd";// change accordingly

            check(Host, mailStoreType, username, password);

        }
    }

    public static void receiveEmail(String Host, String storeType,  String username, String password)
{
    try
    {
        Properties properties = new Properties();  
        properties.put("mail.imap.com", Host);  
        properties.put("mail.imap.starttls.enable","true");
        properties.put("mail.imap.auth", "true");  // If you need to authenticate

        // Use the following if you need SSL
        properties.put("mail.imap.socketFactory.port", 993);
        properties.put("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        properties.put("mail.imap.socketFactory.fallback", "false");

        Session emailSession = Session.getDefaultInstance(properties);  
        emailSession.setDebug(true);

        //2) create the IMAP store object and connect with the Imap server  
        IMAPStore emailStore = (IMAPStore) emailSession.getStore(storeType);

        emailStore.connect(Host, username, password);  

        //3) create the folder object and open it  
        Folder emailFolder = emailStore.getFolder("INBOX");  
        emailFolder.open(Folder.READ_ONLY);  

        //4) retrieve the messages from the folder in an array and print it  
        Message[] messages = emailFolder.getMessages();  
        for (int i = 0; i <messages.length; i++) 
        {
            Message message = messages[i];  
            MimeMessage m = new MimeMessage(emailSession);
            m.setContent(((MimeMessage)messages[i]).getContent() , "text/plain; charset=UTF-8");
            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());  
            m.writeTo(System.out);
        }  

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

    } 
    catch (NoSuchProviderException e) {e.printStackTrace();}   
    catch (MessagingException e) {e.printStackTrace();}  
    catch (IOException e) {e.printStackTrace();}

}

    public void stopThread()
    {
        this.done=true;
    }
}

Ich nenne den Thread von einer anderen Klasse wie dieser

connec=new Connection();
 (new Thread(connec)).start();

Ich erhalte folgende Fehler:

javax.mail.MessagingException: Sun.security.validator.ValidatorException: PKIX path building failed: Sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target;
  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.imap.IMAPStore.protocolConnect(IMAPStore.Java:571)
    at javax.mail.Service.connect(Service.Java:288)
    at javax.mail.Service.connect(Service.Java:169)
    at mailpackage.Connection.check(Connection.Java:63)
    at mailpackage.Connection.run(Connection.Java:33)
    at Java.lang.Thread.run(Thread.Java:744)
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:1884)
    at Sun.security.ssl.Handshaker.fatalSE(Handshaker.Java:276)
    at Sun.security.ssl.Handshaker.fatalSE(Handshaker.Java:270)
    at Sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.Java:1341)
    at Sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.Java:153)
    at Sun.security.ssl.Handshaker.processLoop(Handshaker.Java:868)
    at Sun.security.ssl.Handshaker.process_record(Handshaker.Java:804)
    at Sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.Java:1016)
    at Sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.Java:1312)
    at Sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.Java:882)
    at Sun.security.ssl.AppInputStream.read(AppInputStream.Java:102)
    at com.Sun.mail.util.TraceInputStream.read(TraceInputStream.Java:110)
    at Java.io.BufferedInputStream.fill(BufferedInputStream.Java:235)
    at Java.io.BufferedInputStream.read(BufferedInputStream.Java:254)
    at com.Sun.mail.iap.ResponseInputStream.readResponse(ResponseInputStream.Java:98)
    at com.Sun.mail.iap.Response.<init>(Response.Java:96)
    at com.Sun.mail.imap.protocol.IMAPResponse.<init>(IMAPResponse.Java:61)
    at com.Sun.mail.imap.protocol.IMAPResponse.readResponse(IMAPResponse.Java:135)
    at com.Sun.mail.imap.protocol.IMAPProtocol.readResponse(IMAPProtocol.Java:261)
    at com.Sun.mail.iap.Protocol.<init>(Protocol.Java:114)
    at com.Sun.mail.imap.protocol.IMAPProtocol.<init>(IMAPProtocol.Java:104)
    at com.Sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.Java:538)
    ... 5 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:385)
    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:326)
    at Sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.Java:231)
    at Sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.Java:126)
    at Sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.Java:1323)
    ... 23 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:196)
    at Java.security.cert.CertPathBuilder.build(CertPathBuilder.Java:268)
    at Sun.security.validator.PKIXValidator.doBuild(PKIXValidator.Java:380)
    ... 29 more

ich habe etwas über den PKIX-Pfadfehler gelesen, der besagt, dass das Zertifikat als vertrauenswürdiges Zertifikat zum Java-Speicher hinzugefügt werden soll.

// Ich habe keinen Zugriff auf den Mailserver

Irgendwelche Vorschläge? Vielen Dank! 

21
fnkbz

Ok Problem gelöst!  

Die Lösung ist folgende:

Holen Sie sich zuerst das selbstsignierte Zertifikat vom Mailserver über openssl:

echo | openssl s_client -connect yoursever:port 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > yourcert.pem

Speichern Sie dann die Datei yourcert.pem in diesem Pfad/Library/Java/Home/lib/security (auf macOSX) und legen Sie die cert-Datei wie folgt in die Zertifikate

keytool -keystore cacerts -importcert -alias youralias -file yourcert.pem

Das Standardkennwort für den Keystore lautet changeet

Sie können die Änderung anzeigen, die Sie mit diesem Befehl vorgenommen haben, um den Fingerabdruck des Zertifikats anzuzeigen.

keytool -list -keystore cacerts

Danach sollten Sie diese Argumente in VM übergeben

(Für Windows und Linux geben Sie Ihren Pfad zwischen "") ein.

-Djavax.net.ssl.trustStore="/Library/Java/Home/lib/security/cacerts" 

-Djavax.net.ssl.trustStorePassword="changeit"

Für Debuggen:

-Djava.security.debug=certpath

-Djavax.net.debug=trustmanager

35
fnkbz

Sie können die Upgrade-Bibliothek javax.mail.jar unter https://Java.net/projects/javamail/pages/Home (jetzt Version 1.5.5) ausprobieren und Code hinzufügen:

MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true); 
properties.put("mail.imap.ssl.trust", "*");
properties.put("mail.imap.ssl.socketFactory", sf);
21
TungHarry

einfache Möglichkeit, dieses Problem zu lösen, indem Sie die Zertifikatdatei von Java 7 abrufen

kopieren Sie die Datei "cacerts" aus dem folgenden Java 7-Verzeichnis

C:\Program Files\Java\jdk1.7.0_79\jre\lib\security

und fügen Sie es in das Java 6-Verzeichnis ein

C:\Program Files\Java\jdk1.6.0\jre\lib\security
2
Baji Shaik

Dieser JavaMail-Eintrag FAQ sollte helfen.

Zitierter Text von der verlinkten Seite:

F: Beim Herstellen einer Verbindung zu meinem Mail-Server über SSL erhalte ich eine Ausnahme wie "Es wurde kein gültiger Zertifizierungspfad zum angeforderten Ziel gefunden".

A: Ihr Server verwendet wahrscheinlich ein Testzertifikat oder ein selbstsigniertes Zertifikat anstelle eines von einer kommerziellen Zertifizierungsstelle signierten Zertifikats. Sie müssen das Zertifikat des Servers in Ihrem Trust Store installieren. Das InstallCert-Programm hilft dabei.

Alternativ können Sie die Eigenschaft "mail.protocol.ssl.trust" auf den Hostnamen Ihres Mail-Servers setzen. Weitere Informationen finden Sie in den Javadocs für die Protokollanbieterpakete.

Andere häufige Ursachen für dieses Problem sind:

  • Es gibt ein Firewall- oder Antivirenprogramm, das Ihre Anfrage abfängt.
  • In Ihrer JDK-Installation stimmt etwas nicht, damit die Zertifikate für die vertrauenswürdigen Zertifizierungsstellen nicht gefunden werden können.
  • Sie führen einen Anwendungsserver aus, der die Liste der vertrauenswürdigen Zertifizierungsstellen des JDK überschrieben hat.
1
Bill Shannon

Ich bin auch auf dieses Problem gestoßen, wenn ich mit einem Mailserver spreche. Die Hauptursache war jedoch, dass auf dem Server (Exchange 2013) sowohl ein echtes Zertifikat UND ein selbstsigniertes Zertifikat angewendet wurden. Die geeignete Vorgehensweise bestand darin, die selbstsignierten Server auf dem Server zu entfernen, da dieser Vorrang hatte und das eigentliche Zertifikat blockierte.

0
Brian Knoblauch

Ich musste ersetzen:

props.setProperty("mail.smtp.starttls.enable", "true");
props.setProperty("mail.smtp.auth", "true");

mit:

props.put("mail.smtp.starttls.enable", true);
props.put("mail.smtp.auth", true);

den Fehler loswerden.

Beachten Sie, dass ich Steg 9 verwende, der eine alte Javamail-Version enthält.

Ich habe dies veröffentlicht, da der Fehler nicht bedeuten muss, dass mit dem Zertifikat etwas nicht stimmt.

0
Tinus Tate

Ich habe so viele Tage auf der Suche nach einer Lösung verloren, und dieser Beitrag hat mir geholfen. Ich hatte das gleiche Problem. Ich habe eine Pem-Datei wie hier erstellt, und dann wurde die Zert-Datei .pem mit diesem Befehl in eine cacert-Datei (eine Kopie namens TrustStore.jks) inkrustiert:

keytool.exe -import -noprompt -keystore TrustStore.jks -storepass change ^ Alias ​​DOMAINNAME -Datei MYCERTFILE.pem

(DOMAINNAME muss durch den Hostnamen ersetzt werden -dieser Trick ist sehr wichtig- und MYCERTFILE durch die zuletzt erstellte Datei ...)

Ich hoffe, dass diese Lösung jemandem helfen kann.

0
titojusto