导入证书后仍然获得SunCertPathBuilderException

时间:2013-10-01 10:51:20

标签: java ssl ssl-certificate sslhandshakeexception

我正在尝试通过ssl连接到ldap服务器,我获得了服务器证书并按如下方式安装:

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

我得到证书已成功安装消息,我可以使用以下命令验证证书是否已安装:

keytool -list -keystore cacerts

我可以在可信证书列表中找到我的证书。

这是我如何连接到ldap服务器:

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;
        }
    }

从cmd安装证书后,尝试运行应用程序我仍然得到例外:

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)

我尝试在连接到ldap之前使用 disableCertificateValidation 方法,如帖子Java client certificates over HTTPS/SSL

但它也有同样的例外。

请告知我为什么仍然会收到此错误。

2 个答案:

答案 0 :(得分:2)

您不应修改JDK附带的cacerts文件。复制它并将证书添加到您自己的文件中,并通过系统属性javax.net.ssl.trustStore告诉JSSE。

答案 1 :(得分:0)

原因1:有两个冲突的JDK安装,删除其中一个并重新导入密钥,一切正常。

原因2:在某些测试机器上我必须从

复制生成的cacerts文件

java / jdk / jre / lib / security 进入 java / jre / lib / security

原因3:如果您在websphere服务器上运行代码,则必须按照此处的说明配置来自wensphere的密钥库和证书:

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