關於TLS的一些基本信息我這里就不多說了,網上一搜一大堆。這里主要說一下,在tls單向認證里,怎么用keytool命令去制作CA證書,簽發二級證書。雙向認證也就是照着反方向做一遍就好了。
先附一張簡單的步驟圖,及每一步的命令
1. keytool -certreq -alias server -keystore d:\server.keystore -storepass 123456 -file d:\server.csr
23. keytool -gencert -alias ca -keystore d:\ca.keystore -storepass 123456 -infile d:\server.csr -outfile d:\server.cer
4. keytool -exportcert -alias ca -keystore d:\ca.keystore -storepass 123456 -file d:\ca.cer
5. keytool -importcert -alias ca -keystore d:\server.keystore -storepass 123456 -file d:\ca.cer
6. keytool -importcert -alias server -keystore d:\server.keystore -storepass 123456 -file d:\server.cer
7. keytool -importcert -alias ca -keystore d:\client.keystore -storepass 123456 -file d:\ca.cer
一、明確幾個文件類型
keystore:密鑰庫。可以理解為一種數據庫,里面存的是受信任的公鑰和自己的私鑰,可以存多個。服務端和客戶端各有一個。常見的文件后綴有keystore,jks,p12等等
csr:證書簽名請求文件。是由keystore文件里的自簽名證書(后面會說是什么)生成出來的,一般於給CA機構,對該文件進行簽名。簽名后會變為cer文件。
cer:證書文件。就是一般我們所說的證書了,里面保存了公鑰和主體信息。常見的文件后綴有cer,crt,rsa等。
二、生成客戶端,服務端,CA,三者的密鑰庫
因為要模擬單向認證的tls,同時需要CA認證體系,所以我們一共需要三個密鑰庫。所謂CA,其實本質上就是一個被大家都信任的密鑰對所有者。在jdk/bin/目錄下,有keytool命令。如果嫌麻煩也可以設置環境變量。
client.keystore
keytool -genkeypair -alias client -keystore d:\client.keystore -storepass 123456
說一下每個參數的含義
-genkeypair:生成一個密鑰對
-alias:密鑰對別名
-keystore:要生成密鑰庫的路徑
-storepass:密鑰庫密碼
然后另外兩個密鑰庫同理:
server.keystore
keytool -genkeypair -alias server -keystore d:\server.keystore -storepass 123456
ca.keystore
keytool -genkeypair -alias ca -keystore d:\ca.keystore -storepass 123456
現在,我們有了三個文件,客戶端的密鑰庫文件client.keystore,服務端的密鑰庫server.keystore,CA的密鑰庫ca.keystore
密鑰庫中存儲的是密鑰對,如何查看呢?以client為例, 可以看到,里面有一個別名為client的密鑰對了
keytool -list -keystore d:\client.keystore -storepass 123456 -v
如果想看詳情,在命令后加“-v”,注意此處的證書鏈長度為1,一會經過CA簽發后,會變成2。證書[1]里的所有者和發布者都是自己,這種就叫自簽名證書。
三、服務端生成證書簽名請求文件
因為我們要做的是tls單向認證,所以是服務端需要到CA去進行簽名認證。
服務端需要通過自己的server.keystore,來生成一個證書簽名請求文件(*.csr),給到CA去。
keytool -certreq -alias server -keystore d:\server.keystore -storepass 123456 -file d:\server.csr
會發現,d盤根目錄下,多了一個csr文件
四、CA對證書請求文件進行簽發
作為CA,你會收到用戶(也就是需要被CA簽發的機構,這里是指服務端)給你的csr文件,你需要用自己的ca.keystore密鑰庫中的密鑰對,對這個csr文件進行簽發
keytool -gencert -alias ca -keystore d:\ca.keystore -storepass 123456 -infile d:\server.csr -outfile d:\server.cer
簽發后,就會生成一個cer證書文件。需要把這個cer文件還給服務端。
五、服務端需要將cer證書導入到自己的密鑰庫中
服務端需要將CA給自己的server.cer,導入到自己的server.keystore中。
注意,這里有個坑!因為我們的CA也是自己的,它並不被任何人信任。如果你試圖直接將server.cer文件導入到server.keystore文件中,會報錯如下:無法從回復中建立鏈
所以在導入cer文件前,需要讓CA先生成自己的自簽名證書,導入到服務端的密鑰庫中(其實客戶端也需要導入,但這里不導入不會影響什么,我們下面第六步再做)
CA先要生成自己的自簽名證書文件,直接一步,用自己ca.keystore,生成了cer文件,不用再生成csr文件。
keytool -exportcert -alias ca -keystore d:\ca.keystore -storepass 123456 -file d:\ca.cer
服務端需要將ca.cer導入到自己的server.keystore文件中
keytool -importcert -alias ca -keystore d:\server.keystore -storepass 123456 -file d:\ca.cer
接下來就可以導入,第四步里CA給我的cer文件了。可以看到,不再報錯
導入的時候,起的別名一定要和導出csr文件時用的密鑰對一致,我這里的別名是server。別名一致的時候,才能讓原有的證書變成證書鏈。
keytool -importcert -alias server -keystore d:\server.keystore -storepass 123456 -file d:\server.cer
這個時候,我們再看服務端密鑰庫里,server密鑰對的詳情,就會發現變成了證書鏈,長度變成了2。現在的證書[1]發布者,也變成了CA。原來的證書[1],就變成了下面的證書[2]
keytool -list -keystore d:\server.keystore -storepass 123456 -v
六、將CA的ca.cer導入到客戶端的密鑰庫中
第五步說了,ca.cer不光要導入到服務端的密鑰庫中,也需要導入到客戶端的client.keystore中去
keytool -importcert -alias ca -keystore d:\client.keystore -storepass 123456 -file d:\ca.cer
至此,CA根證書制作完畢,也已經簽發了二級證書server.cer。
現在三個密鑰庫中的情況是:
client中有自己的密鑰對“client”,信任的ca證書“ca”
server中有自己的密鑰對“server”,信任的ca證書“ca”,其中,“server”證書是一個證書鏈
ca中有自己的密鑰對“ca”
tls單向認證的時候,客戶端加載client.keystore文件即可,服務端加載server.keystore即可