<b>目錄結構</b>
一.概念介紹:windows域,域控
二.環境及說明
三.總體過程
四.ad證書安裝過程
五.ad證書的導出與導入
六.ad證書導入java密鑰庫中
七.java編碼實作
八.問題說明
<b>一.概念介紹</b>
本文摘要:ad證書安裝過程,ad證書的導出與導入,ad證書導入java密鑰庫中,java實作ldap改密,環境及說明
windows域:域常跟工作組做對比,這倆個概念有相似的地方,不了解域的可以參照工作組了解。但是,域一般是用在比較大的網絡裡,工作組則較小;域是有安全邊界的,一個域内計算機建立信任關系。那麼在域内通路其他機器,不再需要被通路機器的許可,需要一台計算機作為域控伺服器。
域控:能安全集中管理域中賬戶密碼、管理政策等構成資料庫,統一安全政策。包含這個域的賬号,密碼屬于這個域的計算機等資訊構成的資料庫。
<b>二.環境及說明</b>
1.安裝active directory 的伺服器(我使用的域名為hgcs.local)
2.安裝證書服務(需安裝企業根證書)的伺服器,此伺服器加入hdcs域中(也可以用域控作為證書伺服器,我的就是)
3.安裝java應用的計算機,此伺服器不需要加入hgcs域中(我是用的是mac電腦,win電腦參照進行修改)
說明: ldap 無法直接擷取windows active directory 使用者密碼,需要通過一個安全的通道(我這裡用的是ssl)
<b>三.總體過程</b>
1 安裝active directory 域控制器
2 安裝證書服務
3 以域使用者登入到安裝了證書服務的伺服器中,導出域根證書和計算機證書
4 将證書倒入java密鑰庫中
5 編碼實作
<b>四.ad證書安裝過程</b>
說明:這裡我用的伺服器是 windows server 2008
*如果是第一次安裝,為了避免出錯,下列步驟中能勾選的複選框都選上。
*因伺服器而異,在安裝過程中,仔細閱讀windows的說明資訊,根據自己的需求作響應調整。
1.windows server,進入伺服器管理器,如圖4.1所示。
圖4.1 伺服器管理器
2.伺服器管理器,選擇角色,右擊,添加角色,如圖4.2所示
圖4.2 添加角色
3.添加角色第一步,選擇下一步,如圖4.3所示
圖4.3 添加角色-第一步
4.添加角色第二步,選擇active directory,下一步,如圖4.4所示
圖4.4 添加角色-第二步
5.添加角色第三步,選擇證書頒發機構web注冊,會彈出添加角色向導,點選添加必須的角色服務,(這裡注意能選的都選上,或者仔細讀win說明)如圖4.5所示
圖4.5 添加角色-第三步
6.添加角色第四步,選擇安裝類型-企業,如圖4.6所示
圖4.6 添加角色-第四步
7.添加角色第五步,選擇ca類型-根ca,如圖4.7所示
圖4.7 添加角色-第五步
8.添加角色第六步,選擇建立私鑰,如圖4.8所示
圖4.8 添加角色-第六步
9.添加角色第七步,這裡我用的是預設,密鑰字型長度2048,雜湊演算法啥sha1,如圖4.9所示
圖4.9 添加角色-第七步
10.添加角色第八步,輸入ca及dc,如圖4.10所示
圖4.10 添加角色-第八步
11.添加角色第九步,這裡怕錯的話能選的都選上,如圖4.11所示
圖4.11添加角色-第九步
11.添加角色第十步,至此安裝成功,如圖4.12所示
圖4.12添加角色-第九步
<b>五.ad證書導出</b>
說明:這裡将導出的ad證書導入到java密鑰庫中,根據實際情況靈活使用。
*如果是第一次安裝,為了避免出錯,把能勾選的複選框都選上。
*這裡要導出倆個證書,域根證書和計算機證書
1.使用快捷鍵win+r進入‘運作’,輸入mmc進入控制台,如圖5.1。
圖5.1進入控制台
2.進入控制台,如果還沒節點,如圖5.2。可以添加,這裡需要證書的節點。
圖5.2控制台-空
3.添加管理單元,右擊檔案,選擇添加/删除管理單元(本地計算機),如圖5.3所示。
圖5.3添加管理單元
4.管理單元,選擇‘證書’節點,點選添加,确定,如圖5.4所示。
圖5.4添加證書節點
5.添加完‘證書’節點後,打開‘個人’,‘證書’,選擇要導出的證書,如圖5.5所示。
圖5.5導出證書,第一步
6.右擊需要的證書,選擇‘所有任務’,‘導出’,導出證書,如圖5.6所示。
圖5.6導出證書,第二步
7.進入證書導出時,基本都是選擇‘預設’直接下一步,下一步就可以,如圖5.7所示。
圖5.7導出證書,第三步
8.如果證書清單裡隻有一個證書,可能缺少計算機證書,可以根據步驟8,9申請新證書,再參照1-7導出證書,如圖5.8所示。
圖5.8申請新證書
9.申請新證書要選擇證書類型為‘計算機’,其他選擇預設,如圖5.9所示。
圖5.9申請新證書-要點
<b>六.ad證書導入java密鑰庫中</b>
說明: 将從證書中導出的兩個證書檔案,*.cer 使用java的keytool工具建立或導入證書庫檔案中
這裡我導出時,根證書命名為‘adroot.cer ’ ,計算機證書命名為‘ad.cer’
/library/java/javavirtualmachines/jdk1.8.0_111.jdk/contents/home是我java根目錄
/library/java/javavirtualmachines/jdk1.8.0_111.jdk/contents/home/bin 下有keytool工具
/users/handongchen/desktop/adroot.cer 是我證書的位置
/library/java/javavirtualmachines/jdk1.8.0_111.jdk/contents/home/bin/keytool -import -keystore security.keystore -file /users/handongchen/desktop/adroot.cer
/library/java/javavirtualmachines/jdk1.8.0_111.jdk/contents/home/bin/keytool -import -keystore security.keystore -alias comkey -file /users/handongchen/desktop/ad.cer
終端提示證書導入到密鑰庫,且沒報錯,說明證書導入完成,這時一定要看下security.keystore在那,我的是在/users/xxxx/security.keystore
也有可能在/library/java/javavirtualmachines/jdk1.8.0_111.jdk/contents/home/jre/lib/security目錄下。我的證書密碼是“123456”
<b>七.java編碼實作</b>
import java.util.hashtable;
import javax.naming.context;
import javax.naming.directory.basicattribute;
import javax.naming.directory.dircontext;
import javax.naming.directory.modificationitem;
import javax.naming.ldap.initialldapcontext;
import javax.naming.ldap.ldapcontext;
public class ldaptest {
@suppresswarnings({ "unchecked", "rawtypes" })
public static void main(string[] args) {
// ladp的一些配置
hashtable env = new hashtable();
//string adminname = "[email protected]"; //管理者賬号
string adminname = "cn=administrator,cn=users,dc=hgcs,dc=local"; //管理者賬号
string adminpassword = "root.1234"; //管理者密碼
string username = ("cn=wph1,cn=users,dc=hgcs,dc=local"); //使用者
//string username = ("[email protected]"); //使用者
string newpassword = "root.1234"; //使用者新密碼
string keystore = "/users/xxxx/security.keystore";
system.setproperty("javax.net.ssl.truststore", keystore);
system.setproperty("javax.net.ssl.truststorepassword", "123456");
env.put(context.initial_context_factory, "com.sun.jndi.ldap.ldapctxfactory");
env.put(context.security_authentication, "simple");
env.put(context.security_principal, adminname);
env.put(context.security_credentials, adminpassword);
env.put(context.security_protocol, "ssl");
string ldapurl = "ldaps://192.168.23.156:636";
env.put(context.provider_url, ldapurl);
try {
// 初始化ldapcontext
ldapcontext ctx = new initialldapcontext(env, null);
modificationitem[] mods = new modificationitem[1];
string newquotedpassword = "\"" + newpassword + "\"";
byte[] newunicodepassword = newquotedpassword.getbytes("utf-16le");
mods[0] = new modificationitem(dircontext.replace_attribute,
new basicattribute("unicodepwd", newunicodepassword));
// 修改密碼
ctx.modifyattributes(username, mods);
system.out.println("reset password for: " + username);
ctx.close();
} catch (exception e) {
system.out.println("problem resetting password: " + e);
e.printstacktrace();
}
<b>八.問題說明</b>
說明:下面是我寫的catch裡對錯誤的判斷,可以參照
catch (exception e) {
/*
* 根據ldap傳回碼判斷錯誤原因并傳回
*/
if (e.tostring().indexof("ldap: error code") > 0) {
// 得到ldap傳回的錯誤嗎
string errormsg = e.tostring();
int startnum = errormsg.tostring().indexof("ldap: error code") + 17;
errormsg = errormsg.substring(startnum, startnum + 19);
int endnum = errormsg.tostring().indexof(" - ");
errormsg = errormsg.substring(0, endnum);
if ("49".equals(errormsg)) {
errormsg = "域控管理者賬戶/密碼錯誤";
} else if ("32".equals(errormsg) || "34".equals(errormsg)) {
errormsg = "域内賬戶錯誤";
} else if ("10".equals(errormsg)) {
errormsg = "dc錯誤";
} else {
errormsg = "修改失敗,錯誤嗎:" + errormsg;
system.out.println("problem resetting password(ldap):" + errormsg);
return errormsg;
if (e.tostring().indexof(
"algorithm: default, provider: sunjsse, class: sun.security.ssl.sslcontextimpl$defaultsslcontext") > 0) {
system.out.println("problem resetting password(ldap):" + "證書無效/證書密碼錯誤");
return "修改失敗,證書無效/證書密碼錯誤";
"the trustanchors parameter must be non-empty") > 0) {
system.out.println("problem resetting password(ldap):" + "證書不存在");
return "修改失敗,證書不存在";
return "修改失敗!";
}