2013-05-30 38 views
1

我唱歌Java和tring更改AD中的密碼。我已將證書導入服務器,但在證書中出現錯誤。ssl證書到AD密碼更改

進口的有效:

keytool -import -keystore "C:\Program Files\Java\jre6\lib\security\cacerts" -trustcacerts -alias openldap -file "C:\certnew.cer" 

名單的有效期:

keytool -list -keystore "C:\Program Files\Java\jre6\lib\security\cacerts" 

我的代碼:

public class PassChange 
{ 
    public static void main (String[] args) { 

    Hashtable env = new Hashtable(); 
    String userName = "CN=optimus,DC=ad,DC=euclid,DC=com"; 

    String oldPassword = "euclid!23"; 
    String newPassword = "kcube!23"; 

    //Could also do this via command line java -Djavax.net.ssl.trustStore.... 

    String keystore = "C:\\Program Files\\Java\\jre6\\lib\\security\\cacerts"; 

    // 1 String keystore = "C:\\Program Files\\Java\\jre6\\lib\\security\\cacerts"; 
    // 2 String keystore = "C:\\Program Files\\Java\\jre6\\lib\\security\\cacerts.jks"; 
    // 3 String keystore = "c:\\"; 
    // 1,2,3 all error 

    System.setProperty("javax.net.ssl.trustStore", keystore); 

    env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); 
    //set security credentials, note using simple cleartext authentication 
    env.put(Context.SECURITY_AUTHENTICATION,"simple"); 
    env.put(Context.SECURITY_PRINCIPAL,userName); 
    env.put(Context.SECURITY_CREDENTIALS,oldPassword); 

    //specify use of ssl 
    env.put(Context.SECURITY_PROTOCOL,"ssl"); 

    //connect to my domain controller 
    String ldapURL = "ldaps://xxx.xxx.xxx.xxx:636"; 
    env.put(Context.PROVIDER_URL,ldapURL); 

    try { 

     // Create the initial directory context 
     LdapContext ctx = new InitialLdapContext(env,null); 

     //change password is a single ldap modify operation 
     //that deletes the old password and adds the new password 
     ModificationItem[] mods = new ModificationItem[2]; 
     String oldQuotedPassword = "\"" + oldPassword + "\""; 
     byte[] oldUnicodePassword = oldQuotedPassword.getBytes("UTF-16LE"); 
     String newQuotedPassword = "\"" + newPassword + "\""; 
     byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE"); 

     mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, new BasicAttribute("unicodePwd", oldUnicodePassword)); 
     mods[1] = new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute("unicodePwd", newUnicodePassword)); 

     ctx.modifyAttributes(userName, mods); 

     System.out.println("Changed Password for: " + userName);  
     ctx.close(); 

    } 
    catch (NamingException e) { 
     System.err.println("Problem changing password: " + e); 
    } 
    catch (UnsupportedEncodingException e) { 
     System.err.println("Problem encoding password: " + e); 
    } 
} 
} 

錯誤消息:

p更改密碼:javax.naming.CommunicationException:簡單綁定失敗:xxx.xxx.xxx.xxx:636 [根異常是javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路徑構建失敗:sun。 security.provider.certpath.SunCertPathBuilderException:無法找到要求的目標的有效證書路徑]

+0

要分析SSL證書有什麼問題,請嘗試使用其他屬性javax.net.debug = all運行該程序。然後用調試輸出更新您的文章。另請參閱http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/ReadDebug.html。 – Matej

+0

javax.net.debug =全部模式.............最後一行錯誤------------------------- ------------>線程0,被稱爲closeSocket() 線程0,處理異常:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路徑構建失敗: sun.security.provider.certpath.SunCertPathBuilderException:無法找到有效的證書路徑到請求的目標 – user2436284

回答

0

您導入了哪個證書?你不需要服務器證書。而是您需要證書頒發機構的公鑰。具體來說,交換機-trustcacerts意在表明這是一個CA公鑰。

按名稱猜測,不知您是否抓取了服務器的證書。

+0

回答謝謝^ ^我有一個服務器證書。 從服務器向客戶端頒發證書正在使用副本。 如果是這樣,我是否需要認證機構的公鑰? – user2436284

+0

@ user2436284用於LDAP over SSL訪問的客戶端應該在JRE的cacerts文件中爲您的CA提供受信任的CA證書。導入過程中的keytool開關很重要的是'-trustcacerts' – geoffc