enviar - Error en JavaMail: la creación de rutas PKIX falló al no poder encontrar una ruta de certificación válida para el objetivo solicitado
enviar email java sin autenticar (6)
Perdí tantos días buscando una solución, y esta publicación fue útil para mí. Yo tuve el mismo problema. Creé un archivo pem como aquí, y luego, el archivo cert .pem, se incrustó en el archivo cacert (una copia llamada TrustStore.jks) con este comando:
keytool.exe -import -noprompt -keystore TrustStore.jks -storepass changeit ^ -alias DOMAINNAME -file MYCERTFILE.pem
(DOMAINNAME debe reemplazarse por nombre de host -este truco es muy importante-, y MYCERTFILE por archivo creado recientemente ...)
Espero que esta solución pueda ayudar a alguien.
Estoy intentando crear una aplicación cliente de correo electrónico en Android y ahora mismo quiero configurar la parte javaMail.
Estoy tratando de establecer la conexión con el servidor imap pero algo está mal con mi código ... aquí está mi código:
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;
}
}
Llamo el hilo de otra clase como esta
connec=new Connection();
(new Thread(connec)).start();
Obtengo los siguientes errores:
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
Leí algo sobre el error de ruta de PKIX que dice agregar el certificado a la tienda Java como un certificado de confianza, pero no sé si esta es la solución para esto, y si es que no sé cómo hacerlo.
// no tengo acceso al servidor de correo
¿Alguna sugerencia? ¡Gracias!
Puede probar la actualización de la biblioteca javax.mail.jar en https://java.net/projects/javamail/pages/Home (ahora la versión es 1.5.5) y agregar el código:
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
properties.put("mail.imap.ssl.trust", "*");
properties.put("mail.imap.ssl.socketFactory", sf);
También me he encontrado con este problema cuando hablo con un servidor de correo. Sin embargo, la causa principal fue que el servidor (Exchange 2013) tenía un certificado real Y se le había aplicado un autofirmado. El curso de acción apropiado fue eliminar el auto-firmado en el servidor porque estaba teniendo prioridad y bloqueando el certificado real.
Una forma fácil de resolver este problema obteniendo un archivo de certificado de Java 7
Copie el archivo "cacerts" del siguiente directorio java 7
C:/Program Files/Java/jdk1.7.0_79/jre/lib/security
y pégalo en el directorio java 6
C:/Program Files/Java/jdk1.6.0/jre/lib/security
Esta entrada de preguntas frecuentes de JavaMail debería ayudar.
Texto citado del sitio vinculado:
P: Cuando me conecto a mi servidor de correo a través de SSL obtengo una excepción como "no se puede encontrar una ruta de certificación válida para el objetivo solicitado".
R: Es probable que su servidor esté utilizando un certificado de prueba o un certificado autofirmado en lugar de un certificado firmado por una autoridad certificadora comercial. Deberá instalar el certificado del servidor en su tienda de confianza. El programa InstallCert te ayudará.
Alternativamente, puede establecer la propiedad "mail.protocol.ssl.trust" en el nombre de host de su servidor de correo. Ver los javadocs para los paquetes de proveedor de protocolo para más detalles.
Otras causas comunes de este problema son:
- Hay un firewall o un programa anti virus que intercepta su solicitud.
- Hay algo mal en su instalación JDK que le impide encontrar los certificados para las autoridades de certificación confiables.
- Se está ejecutando en un servidor de aplicaciones que ha anulado la lista de autoridades de certificación de confianza del JDK.
Ok problema resuelto!
La solución es esta:
Primero obtenga el certificado autofirmado del servidor de correo a través de openssl:
echo | openssl s_client -connect yoursever:port 2>&1 | sed -ne ''/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'' > yourcert.pem
A continuación, guarde el archivo yourcert.pem en esta ruta / Library / Java / Home / lib / security (en macOSX) y coloque el archivo cert en los cacerts como este
keytool -keystore cacerts -importcert -alias youralias -file yourcert.pem
La contraseña predeterminada del almacén de claves es changeit
Puede ver el cambio que realizó con este comando que muestra la huella digital del Certificado.
keytool -list -keystore cacerts
Después de esto, debes pasar estos argumentos en VM
(para windows y linux escriba yourpath entre "")
-Djavax.net.ssl.trustStore="/Library/Java/Home/lib/security/cacerts"
-Djavax.net.ssl.trustStorePassword="changeit"
Para depurar:
-Djava.security.debug=certpath
-Djavax.net.debug=trustmanager