JavaMail para enviar correo electrónico seguro a través de vps - SSLHandshake Exception, falla en la construcción de la ruta PKIX, etc. - No se puede enviar correo

I'm testing out sending email through my vps and I've run into a problem when it comes to sending a secure mail through SMTPS. SMTP and POP3 functions work, as the email is successfully sent. SMTPS doesn't.

I setup a simple test (JSP) page to send off an email. The code is provided below.

           Transport t = null; 


   try {   

      String SMTPS = "mydomainname.com";          

      String Username = "maindomainemail";
      String Password = "myhiddenpassword"; 

            InternetAddress from = new InternetAddress("mrsmith@mydomainname.com", "Bob Smith");         

         Properties props = new Properties();               

      props.setProperty("mail.smtps.auth", "true");      

   props.put("mail.smtps.host", "mydomainname.com");


    String protocol = "smtps";    
    Session ssn = Session.getInstance(props, null);

       ssn.setDebug(true);            

    t = ssn.getTransport(protocol);            
    t.connect(SMTPS,Username,Password);                   

       InternetAddress to = new InternetAddress("mypersonalemail@hotmail.com", "Tom Smith");

       String subject = "testing email";

       String newBody = "message body of email";

          // Create the message
          Message msg = new MimeMessage(ssn);
          msg.setFrom(from);
          msg.addRecipient(Message.RecipientType.TO, to);
          msg.setSubject(subject);
          msg.setContent(newBody, "text/html");
    t.sendMessage(msg, msg.getAllRecipients());                  
    t.close();  

        }//try
             catch (MessagingException mex) {
              mex.printStackTrace(); }          
         catch(Exception e) {}

On my vps, I had to follow instructions to setup secure smtp.

After running the jsp test page, I'm getting the following exceptions in my tomcat log file.

INFO   | jvm 1    | 2011/01/06 12:29:11 | DEBUG: setDebug: JavaMail version 1.4.1
INFO   | jvm 1    | 2011/01/06 12:29:11 | DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc]
INFO   | jvm 1    | 2011/01/06 12:29:11 | DEBUG SMTP: useEhlo true, useAuth true
INFO   | jvm 1    | 2011/01/06 12:29:11 | DEBUG SMTP: trying to connect to host "mydomainname.com", port 465, isSSL true
INFO   | jvm 1    | 2011/01/06 12:29:12 | DEBUG SMTP: exception reading response: 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
INFO   | jvm 1    | 2011/01/06 12:29:12 | javax.mail.MessagingException: Exception reading response;
INFO   | jvm 1    | 2011/01/06 12:29:12 |   nested exception is:
INFO   | jvm 1    | 2011/01/06 12:29:12 |  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
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:1611)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1369)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:412)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at javax.mail.Service.connect(Service.java:288)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at javax.mail.Service.connect(Service.java:169)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.jsp.SendEmailViaEappsVPS_005fSMTPS_jsp._jspService(SendEmailViaEappsVPS_005fSMTPS_jsp.java:112)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:774)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:703)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:896)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at java.lang.Thread.run(Thread.java:595)
INFO   | jvm 1    | 2011/01/06 12:29:12 | 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
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1584)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:848)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:877)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1089)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:737)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:110)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at java.io.BufferedInputStream.read(BufferedInputStream.java:235)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.mail.util.LineInputStream.readLine(LineInputStream.java:88)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:1589)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  ... 26 more
INFO   | jvm 1    | 2011/01/06 12:29:12 | Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:221)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:145)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at sun.security.validator.Validator.validate(Validator.java:203)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:841)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  ... 38 more
INFO   | jvm 1    | 2011/01/06 12:29:12 | Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:236)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:194)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:216)
INFO   | jvm 1    | 2011/01/06 12:29:12 |  ... 43 more

What does this mean? Has anyone seen this type of exception before? What steps do I need to take to fix this problem?

preguntado el 08 de enero de 11 a las 20:01

2 Respuestas

Java is not finding the SSL certification, you need to manually add the host. You need to add server's certification to keystore implying it's your trusted server. You can use this tool here to resolve. http://blogs.sun.com/andreas/entry/no_more_unable_to_find

Espero que esto ayude.


The article seem to be no more availble. I could find small bits of it here and there and tried to re-post it in full. Please visit the following webpage http://cold-caffein.blogspot.com/2011/07/looks-like-article-no-more-unable-to.html

Respondido 03 Jul 11, 22:07

Do you feel that its necessary to send 'secure' email? Or can I just use smtp, and not smtps, and be okay? - katura

Ideally, you should use SMTPS to avoid any man-in-the-middle attack. en.wikipedia.org/wiki/Man-in-the-middle_attack But depends on your company's policy. - Nishant

Anyone know where this link now points to? It's 404 right now :( - GreenKiwi

@GreenKiwi -- sadly, that page seem to be gone. I have posted the duplicate of that page, you may look at it here http://cold-caffein.blogspot.com/2011/07/looks-like-article-no-more-unable-to.html - Nishant

Alternatively, with JavaMail 1.5.2, you can use the 'Socket Factory'-Approach as described in the official SSLNOTES.txt:

JavaMail now includes a special SSL socket factory that can simplify dealing with servers with self-signed certificates. While the recommended approach is to include the certificate in your keystore as described above, the following approach may be simpler in some cases.

The class com.sun.mail.util.MailSSLSocketFactory can be used as a simple socket factory that allows trusting all hosts or a specific set of hosts. For example:

MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
// or
// sf.setTrustedHosts(new String[] { "my-server" });
props.put("mail.smtp.ssl.enable", "true");
// also use following for additional safety
//props.put("mail.smtp.ssl.checkserveridentity", "true");
props.put("mail.smtp.ssl.socketFactory", sf);

Use of MailSSLSocketFactory avoids the need to add the certificate to your keystore as described above, or configure your own TrustManager as described below.

Respondido 14 Abr '15, 15:04

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.