how to ignore server cert error in javamail
Asked Answered
R

11

27

when i connect to my imap server using imaps,it failes.

can you tell me how to ignore server cert error in javamail

Exception in thread "main"
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:665)
    at javax.mail.Service.connect(Service.java:295)
    at javax.mail.Service.connect(Service.java:176)
    at App20110204.main(App20110204.java:31)
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 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1623)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:198)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:192)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1074)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:128)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:529)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:465)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1120)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1147)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1131)
    at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:507)
    at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238)
    at com.sun.mail.iap.Protocol.<init>(Protocol.java:113)
    at com.sun.mail.imap.protocol.IMAPProtocol.<init>(IMAPProtocol.java:110)
    at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:632)
    ... 3 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:294)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:200)
    at sun.security.validator.Validator.validate(Validator.java:218)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1053)
    ... 15 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:174)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:289)
    ... 21 more

and my source code

Properties prop = new Properties();
prop.put("mail.imap.ssl.checkserveridentity", "false");
prop.put("mail.imap.ssl.trust", "*");

Session session = Session.getDefaultInstance(prop);
Store store = session.getStore("imaps");
store.connect("mail.xxx.com", "xxxx", "p@ssw0rd");
System.out.println(store.getFolder("INBOX").getMessageCount());
Rostrum answered 4/2, 2011 at 5:43 Comment(1)
Possible duplicate of #4062807Lilybel
H
57

use prop.put("mail.imaps.ssl.trust", "*"); since you are using imaps store.

and for smtp you can try : prop.put("mail.smtp.ssl.trust", "*"); .

Haught answered 20/4, 2011 at 12:24 Comment(1)
Using mail.imaps.ssl.trust fixed it for me, strange that the documentation (that I've read) does only mention mail.imap.ssl.trust and never mail.imaps.ssl.trust or any other property mail.imaps.xxx for that matter. I'm assuming mail.imap.ssl.trust is used when starttls is used instead of a SSL tunnel.Rocha
C
34

Don't ignore certificate verification errors (unless perhaps in a test environment): this defeats the point of using SSL/TLS.

Instead, if you know you trust that server certificate, import it in your trust store (either the global trust store of the JRE or a local one that you specify with the javax.net.ssl.trustStore* system properties, for example).

Cecilacecile answered 5/1, 2012 at 9:58 Comment(3)
Ahh, StackOverflow: where secure answers to questions about security get downvoted, and insecure answers get upvoted. Sigh....Coping
This is a great answer. What if you're using a third party code? You can't use any dirty hacks presented in other answers. This one worked, but it could be more specific as to how to add the certificate. What helped me with this, was to realize I had to change jre/lib/security/cacerts, using this advice: martin-probst.com/blog/2008/03/14/… In short: use keytool -import -file your_cert.cer /path/to/cacerts, the password is changeit.Thilda
Given the limitations of 3rd-party commercial singly-rooted CAs, anything less than a trust store whose only CA is yourself is less than complete. Point being, for multi-tenant web applications where the remote endpoint is desired by the client regardless of whether they paid for a commercial certificate, the MITM risk is often deemed acceptable for well-defined endpoints.Arbitrary
X
6
     Properties propsSSL = new Properties();
     propsSSL.put("mail.transport.protocol", "smtps");
     propsSSL.put("mail.smtps.host", "hostname");
     propsSSL.put("mail.smtps.auth", "true");
     propsSSL.put("mail.smtps.ssl.checkserveridentity", "false");
     propsSSL.put("mail.smtps.ssl.trust", "*");

Above changes will fix javax.mail.MessagingException: Could not connect to SMTP host: hostname, port: 465; for the nested exception

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
exception 
Xenogamy answered 26/11, 2012 at 6:44 Comment(0)
K
5

If you are using javamail 1.4.2+, there is a socket factory you can use to ignore server certificate.

MailSSLSocketFactory socketFactory= new MailSSLSocketFactory();
socketFactory.setTrustAllHosts(true);
prop.put("mail.imap.ssl.socketFactory", socketFactory);
Kohn answered 5/1, 2012 at 5:9 Comment(4)
Why bother with SSL if you're willing to trust all hosts anyway... Don't use this in production.Cecilacecile
I agree that we should never use this in production. This is usually for self-signed certificate. I got the same problem for connecting to testing imaps server which use a self-signed certificate. This fixed it for me.Kohn
Thanks, I needed this to connect to Gmail over IMAP as part of a functional test framework.Systematism
@Cecilacecile this is less secure than properly trusting specific certificate(s), and prone to MITM attack, but is still relatively more secure than no encryption at all. I'd say that trusting specific hosts using mail.imaps.ssl.trust or mail.smtp.ssl.trust is better than this.Unthankful
A
2

I think @Bruno is correct to admonish you not to blindly trust all servers with the hack setTrustAllHosts(true)

In the docs at Oracle they show how to add your dev mail host to the trusted list without forcing your app to insecurely trust the whole world:

MailSSLSocketFactory sf = new MailSSLSocketFactory();
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);
Ashurbanipal answered 2/9, 2014 at 16:6 Comment(1)
I thinks this is the best secured solution for a well known and trusted serverBazan
G
1

I was the same issue, using

MailSSLSocketFactory socketFactory= new MailSSLSocketFactory();
socketFactory.setTrustAllHosts(true);
prop.put("mail.pop3s.ssl.socketFactory", socketFactory);

com.sun.mail.util.MailSSLSocketFactory

it's works!!

Girosol answered 21/12, 2012 at 9:6 Comment(0)
M
1
    Properties pr = new Properties();
    MailSSLSocketFactory socketFactory= new MailSSLSocketFactory();
    socketFactory.setTrustAllHosts(true);
    pr.put("mail.pop3s.ssl.socketFactory", socketFactory);
    Session ses = Session.getInstance(pr);
    ses.setDebug(true);
    URLName url =  new URLName("pop3s://username:password@host:posrt");
    Store store = ses.getStore(url.getProtocol());
    store.connect(url.getHost(), url.getPort(), url.getUsername(), url.getPassword());
    Folder inbox = store.getFolder("INBOX");
    inbox.open(Folder.READ_ONLY);
    try {
        int i = inbox.getMessageCount();
        com.sun.mail.pop3.POP3Message mes;
        while (i > 0) {
            mes = (com.sun.mail.pop3.POP3Message) inbox.getMessage(i);
            System.out.println(mes.getContentID());
            i--;
        }
    } finally {
        inbox.close(false);
        store.close();
    }

DEBUG: setDebug: JavaMail version 1.4.5
Exchange server 2010
PlainTextLogin
http://technet.microsoft.com/ru-ru/library/bb124498(v=exchg.141).aspx

Metapsychology answered 31/1, 2013 at 8:47 Comment(0)
Q
1

If It is the problem persisted in Java 6 then the solution is simple.It is just simple as Java 7 was released.Install java 7 in machine.java 7 have the certificates file having the capability of ignoring certificate authentication.

copy the "cacerts" file from following java 7 directory

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

and paste it in

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

now the certificate authentication problem will be resolved.

Quadri answered 4/12, 2015 at 7:10 Comment(0)
B
0

This will help you bypass certificate process and get directly to ssl host

MailSSLSocketFactory sf = null;
try
{
    sf = new MailSSLSocketFactory();
}
catch (GeneralSecurityException e)
{
    e.printStackTrace();
}
        sf.setTrustAllHosts(true);

Properties pop3Props = new Properties();
pop3Props.setProperty("mail.pop3.ssl.enable", "true");
pop3Props.setProperty("mail.protocol.ssl.trust", "pop3.live.com");
pop3Props.put("mail.pop3s.ssl.socketFactory", sf);
pop3Props.setProperty("mail.pop3s.port", "995");

Session session = Session.getInstance(pop3Props);

try
{
/* Get a Store object*/
   Store store = session.getStore("pop3s");
//process further activity 
}
Braziel answered 19/12, 2013 at 12:5 Comment(0)
V
0

I was the same issue.

MailSSLSocketFactory socketFactory = new MailSSLSocketFactory(); socketFactory.setTrustedHosts(new String[] { "my-server"});

socketFactory.setTrustAllHosts(true); props.put("mail.smtps.socketFactory", socketFactory);

it's works!!

Vedic answered 5/12, 2014 at 8:8 Comment(0)
B
0
            client.ServerCertificateValidationCallback = (s, c, h, e) => true;

It's Work Successfully...

Beeves answered 7/3, 2023 at 10:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.