2013-10-01 63 views
0

我試圖通過SSL連接到LDAP服務器後,仍然得到SunCertPathBuilderException,並且我得到了服務器證書,並如下安裝它:導入證書

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

但它也給出了相同的例外。

請告訴我爲什麼我仍然得到這個錯誤。

回答

0

原因1:有兩個衝突的JDK安裝,刪除其中一個並重新導入密鑰,一切正常。

原因2:一些試驗機我不得不生成的cacerts文件從

的java/JDK/JRE/lib/security中的java/JRE/lib/security中

複製上

原因3:如果您運行的必須配置密鑰存儲和wensphere證書,這裏提到的WebSphere服務器上的代碼:

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

2

您不應該修改JDK附帶的cacerts文件。複製它並將證書添加到您自己的文件中,並通過系統屬性javax.net.ssl.trustStore告訴JSSE。