Pergunta

i am trying to connect to ldap server over ssl, and i got the server certificate and installed it as follows:

keytool -keystore cacerts -importcert -alias ldapCert -file LdapCert.cer

and i got certificate was installed successfully message, and i can verify that certificate was installed with the command:

keytool -list -keystore cacerts

and i can find my certificate in the list of trusted certificates.

here's how i am connecting to ldap server:

String host = "server.ip.here;
        String userDN = "CN=myuser,OU=EmployeesOU,OU=MainOU,dc=mydomain,dc=net";
        String userPassword = "mypassword";
        boolean ssl = true;

public static LdapContext connectToLdap(String host,
            String userDN, String userPassword,
            boolean ssl) throws Exception {

        System.out.println("connectToLdap");

        String hostPrefix = "ldap";
        String ldapPort = "389";
        if (ssl) {
            hostPrefix = "ldaps";
            ldapPort = "636";
        }
        String providerUrl = hostPrefix + "://" + host + ":" + ldapPort;
        //System.out.println("####### LDAP URL: " + providerUrl);
        LdapContext ldapContext;
        Hashtable<String, String> ldapEnv = new Hashtable<String, String>(11);
        ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY,
                "com.sun.jndi.ldap.LdapCtxFactory");
        ldapEnv.put(Context.PROVIDER_URL, providerUrl);
        ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
        ldapEnv.put(Context.SECURITY_PRINCIPAL, userDN);
        ldapEnv.put(Context.SECURITY_CREDENTIALS, userPassword);
        ldapEnv.put("com.sun.jndi.ldap.read.timeout", 1000 * 10 + "");
        if (ssl) {
            ldapEnv.put(Context.SECURITY_PROTOCOL, "ssl");
        }
        ldapEnv.put(Context.REFERRAL, "ignore");
        try {
            ldapContext = new InitialLdapContext(ldapEnv, null);
            System.out.println("success connection to ldap");
            return ldapContext;
        } catch (Exception e) {
            System.out.println("failure connection to ldap");
            e.printStackTrace();
            return null;
        }
    }

after installing the certificate from cmd, and trying to run the application i am still getting the exception:

javax.naming.CommunicationException: simple bind failed: server.ip:636 [Root 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.jndi.ldap.LdapClient.authenticate(LdapClient.java:197)
        at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2694)
        at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:293)
        at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:175)
        at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:193)
        at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:136)
        at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:66)
        at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
        at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
        at javax.naming.InitialContext.init(InitialContext.java:223)
        at javax.naming.ldap.InitialLdapContext.<init>(InitialLdapContext.java:134)
        at ldap.LDAPUtils.connectToLdap(LDAPUtils.java:58)
        at Test.main(Test.java:43)
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.readDataRecord(SSLSocketImpl.java:744)
        at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
        at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
        at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
        at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
        at com.sun.jndi.ldap.Connection.run(Connection.java:808)
        at java.lang.Thread.run(Thread.java:619)
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:325)
        at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:219)
        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)
        ... 12 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:320)

i tried to use the disableCertificateValidation method before connecting to ldap as in the post Java client certificates over HTTPS/SSL

but it also gives same exception.

please advise why i am still getting this error.

Foi útil?

Solução 2

Cause 1: having two conflicting installations of JDK, removed one of them and re imported the key and everything worked fine.

Cause 2: on some test machine i had to copy the generated cacerts file from

java/jdk/jre/lib/security into java/jre/lib/security

Cause 3: if you are running the code on websphere server you have to configure key store and certificates from wensphere as mentioned here:

http://www-01.ibm.com/support/docview.wss?uid=swg21316850

Outras dicas

You shouldn't modify the cacerts file that comes with the JDK. Copy it and add the certificate to your own file, and tell JSSE about it via the system property javax.net.ssl.trustStore.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top