Keytool是一個Java資料證書的管理工具, Keytool將金鑰(key)和證書(certificates)存在一個稱為keystore的檔案中。
在keystore裡,包含兩種資料:
我們常說的證書就是就是上面的公鑰,公鑰是公開給其它人使用的
jks
是Java的keytool證書工具支援的證書私鑰格式;pfx
是微軟支援的私鑰格式(p12是pfx的新格式);cer
/ crt
是證書的公鑰格式(cer是crt證書的微軟形式)csr
數位憑證簽名請求檔案(Cerificate Signing Request)Tips:
.der
.cer
: 此證書檔案是二進位制格式,只含有證書資訊,不包含私鑰。.crt
: 此證書檔案是二進位制格式或文字格式,一般為文字格式,功能與 .der
及 .cer
證書檔案相同。.pem
: 此證書檔案一般是文字格式,可以存放證書或私鑰,或者兩者都包含。 .pem
檔案如果只包含私鑰,一般用 .key
檔案代替。.pfx
.p12
: 此證書檔案是二進位制格式,同時包含證書和私鑰,且一般有密碼保護。.keystore
.truststore
: 兩者本質都是keystore,都是儲存金鑰的容器:
truststore
是必須的,如果我們沒有顯式的指定,那麼java會預設指定為 $JAVA_HOME/lib/security/cacerts
這個檔案金鑰和證書管理工具
-certreq 生成證書請求
-changealias 更改條目的別名
-delete 刪除條目
-exportcert 匯出證書(簡寫 export)
-genkeypair 生成金鑰對(簡寫 genkey)
-genseckey 生成金鑰
-gencert 根據證書請求生成證書
-importcert 匯入證書或證書鏈(簡寫 import)
-importpass 匯入口令
-importkeystore 從其他金鑰庫匯入一個或所有條目
-keypasswd 更改條目的金鑰口令
-list 列出金鑰庫中的條目
-printcert 列印證書內容
-printcertreq 列印證書請求的內容
-printcrl 列印 CRL 檔案的內容
-storepasswd 更改金鑰庫的儲存口令
Tips:
使用 ketytool --help
獲取所有可用命令
使用 keytool -command_name -help
來獲取 command_name 的用法
常用引數
-genkey 產生金鑰對(genkeypair 簡寫);表示要建立一個新的金鑰;alias和keystore預設時,在使用者主目錄中建立一個」.keystore」檔案,且別名為mykey,包含使用者的公鑰、私鑰證書
-alias 產生證書別名,和keystore關聯的唯一別名,不區分大小寫(預設 `mykey`)
-keystore 指定金鑰庫檔案的名稱(預設在使用者主目錄建立證書庫)
-keyalg 指定金鑰的演演算法(可選擇金鑰演演算法:`RSA`、`DSA`、`EC`,預設`DSA`)
-keysize 指定金鑰長度(與keyalg預設對應關係:`RSA=2048`、`DSA=2048`、`EC=256`)
-sigalg 指定簽名演演算法(MD5和 SHA1的簽名演演算法已經不安全)
-validity 指定證書有效期天數(預設 `90`天)
-storepass 指定金鑰庫口令,推薦與keypass一致(獲取keystore資訊所需的密碼)
-storetype 指定金鑰庫的型別,可用型別為:JKS、PKCS12等。(jdk9以前,預設為JKS。自jdk9開始,預設為PKCS12)
-keypass 指定別名條目口令(私鑰的密碼)
-dname 指定證書發行者資訊(其中 CN 要和伺服器的域名相同,本地測試則使用localhost,其他的可以不填)
-list 顯示金鑰庫中的證書資訊
-v 詳細輸出,顯示金鑰庫中的證書詳細資訊
-file 指定匯出或匯出的檔名
-export 將別名指定的證書匯出到檔案(exportcert 簡寫)
-import 將已簽名數位憑證匯入金鑰庫(importcert 簡寫)
-printcert 檢視匯出的證書資訊
-delete 刪除金鑰庫中某條目
-keypasswd 修改金鑰庫中指定條目口令
-storepasswd 修改keystore口令
-ext X.509 擴充套件
所有密碼長度必須大於或等於 6 位
keyalg 指定加密演演算法;可以選擇的金鑰演演算法有:RSA、DSA(預設)、EC。
sigalg 指定簽名演演算法(MD5和 SHA1的簽名演演算法已經不安全):
dname 表明了金鑰的發行者身份(Distinguished Names)
建立祕鑰庫(keystore),祕鑰庫是儲存一個或多個金鑰條目的檔案,每個金鑰條目應該以一個別名標識,它包含金鑰和證書相關資訊。
Usage:
keytool -genkey
-alias <alias>
-keyalg RSA
[-sigalg SHA256withRSA]
[-keysize 2048]
-keypass <keypasswd>
-keystore <keystore_file>
-storetype JKS|PKCS12
-storepass <keystore_passwd>
-validity 3650
-dname "CN=github.com,OU=github.com,Inc.,O=Github, Inc.,L=San Francisco,ST=California,C=US"
-ext SAN=dns:github.com,dns:www.github.com,ip:127.0.0.1
Options:
-genkey 產生金鑰對(genkeypair 簡寫)
-alias 證書別名;和keystore關聯的唯一別名,這個alias通常不區分大小寫(預設`mykey`)
-keyalg 指定加密演演算法,RSA:非對稱加密(預設`DSA`)
-sigalg 指定簽名演演算法,可選;
-keysize 指定金鑰長度,可選;
-keypass 指定別名條目口令(私鑰的密碼)
-storetype 生成證書型別,可用的證書庫型別為:JKS、PKCS12等。
-keystore 指定產生的金鑰庫的位置;
-storepass 指定金鑰庫的存取口令,推薦與keypass一致
-validity 證書有效期天數;(預設為 90天)
-dname 表明了金鑰的發行者身份(Distinguished Names)生成證書時,其中 CN 要和伺服器的域名相同,本地測試則使用localhost,其他的可以不填
-ext X.509 擴充套件
Tips:
生成伺服器證書
keytool -genkey -alias server -keyalg RSA -keypass 123456 -keystore ~/ssl/tomcat.jks [-storetype JKS] -storepass 123456 -validity 3650 -dname "CN=localhost" -ext SAN=ip:127.0.0.1
生成使用者端證書,以便讓伺服器來驗證它。為了能將證書順利匯入至IE和Firefox,證書格式應該是PKCS12(使用者端的CN可以是任意值)
keytool -genkey -alias client -keyalg RSA -keypass 123456 -keystore ~/ssl/client.p12 -storetype PKCS12 -storepass 123456 -validity 3650 -dname "CN=client"
此證書檔案不包含私鑰;分為自簽名證書和認證證書,下面分別介紹了兩中證書的生成方式
自簽名證書沒有經過證書認證機構進行認證,但並不影響使用,我們可以使用相應的命令對證書進行匯出;
Usage:
keytool -export
-alias <alias>
-keystore <keystore_file>
-storepass <keystore_passwd>
-file <file_cer>
[-rfc]
Options:
-export 執行證書匯出操作(exportcert 簡寫)
-alias 金鑰庫中的證書條目別名(jks裡可以儲存多對公私鑰檔案,通過別名指定匯出的公鑰證書)
-keystore 指定金鑰庫檔案
-storepass 金鑰庫口令
-file 匯出檔案的輸出路徑
-rfc 使用Base64格式輸出(輸出pem編碼格式的證書,文字格式),不適用則匯出的證書為DER編碼格式
匯出伺服器證書
此處為伺服器的自簽名證書匯出, 如果需要使用認證證書,則生成證書籤名請求
keytool -export -alias server -keystore ~/ssl/tomcat.jks -storepass 123456 -file ~/ssl/server.cer
匯出使用者端證書
雙向認證: 伺服器端信任使用者端,由於不能直接將PKCS12格式的證書庫匯入,所以必須先把使用者端證書匯出為一個單獨的CER檔案
keytool -export -alias client -keystore ~/ssl/client.p12 -storepass 123456 -file ~/ssl/client.cer -rfc
如果想得到證書認證機構的認證,則不使用上述的自簽名證書,需要使用步驟匯出數位憑證並簽發申請(Cerificate Signing Request),經證書認證機構認證並頒發後,再將認證後的證書匯入本地金鑰庫與信任庫。
Usage:
keytool -certreq
-alias <alias>
-keystore <keystore_file>
-storepass <keystore_passwd>
-file <file_csr>
Options:
-certreq 執行證書籤發申請匯出操作
-alias 金鑰庫中的證書條目別名
-keystore 金鑰庫檔名稱
-storepass 金鑰庫口令
-file 輸出的csr檔案路徑
生成證書籤名請求(CSR)
keytool -certreq -alias server -keystore ~/ssl/tomcat.jks -storepass 123456 -file ~/ssl/certreq.csr
檢視生成的CSR證書請求
keytool -printcertreq -file certreq.csr
雙向認證: 將各自的公鑰證書分別匯入對方的信任庫,使使用者端和伺服器端相互信任。
Usage:
keytool -import
[-trustcacerts]
-alias <alias_cer>
-keystore <keystore_file>
-storepass <keystore_passwd>
-file <file_cer>
Options:
-import 執行證書匯入操作(importcert 簡寫)
-alias 指定匯入金鑰庫中的證書別名(指定的條目別名不能與金鑰庫中已存在的條目別名重複(匯入簽發證書除外))
-trustcacerts 將證書匯入信任庫(信任來自 cacerts 的證書)
-keystore 金鑰庫名稱
-storepass 金鑰庫口令
-file 輸入檔名
安裝伺服器證書(將伺服器公鑰證書匯入使用者端)
雙向認證: 使用者端信任伺服器端: 在客戶機器上雙擊證書檔案完成匯入操作(window中匯入)
證書匯入信任庫(將使用者端公鑰證書匯入信任庫)
雙向認證: 伺服器端信任使用者端:
keytool -import -alias clientCert -keystore ~/ssl/truststore.jks -storepass 123456 -file ~/ssl/client.cer
此步驟會生成信任證書 truststore.jks檔案, 檔案存放需要信任的公鑰證書,如使用者端證書(也可以將 keystore值改為伺服器金鑰庫,即tomcat.jks。此時的tomcat.jks 就同時是服務的金鑰庫和信任庫)
Usage:
# 檢視單個證書(cer | crt)
keytool -printcert -file <cert_file> [-v|-rfc]
# 檢視金鑰庫中的證書條目
keytool -list [-alias <alias_name>] -keystore <keystore_file> -storepass <keystore_passwd> [-v|-rfc]
# 檢視生成的CSR證書請求
keytool -printcertreq -file <certreq_file>
Options:
-alias 金鑰庫中的證書條目別名;
-keystore 指定金鑰庫檔案;
-storepass 金鑰庫口令;
-printcert 執行證書列印命令;
-list 預設情況下,命令列印證書的 MD5 指紋。
而如果指定了 -v 選項,將以可讀格式列印證書,
如果指定了 -rfc 選項,將以可列印的編碼格式輸出證書。
檢視證書資訊
keytool -printcert -file ~/ssl/client.cer [-v|-rfc]
檢視金鑰庫
keytool -list -keystore ~/ssl/tomcat.jks -storepass 123456 -v
檢視base64的內容(即PEM編碼)
keytool -list -keystore ~/ssl/tomcat.jks -storepass 123456 -rfc
# 刪除keystore裡面指定證書條目
keytool -delete -alias <alias> -keystore <keystore_file> -storepass <keystore_passwd>
# 修改條目別名
keytool -changealias -keystore <keystore_file> -alias <old_alias> -destalias <new_alias>
# 修改條目密碼
keytool -keypasswd -alias <alias> -keypass <old_keypasswd> -new <new_keypasswd> -keystore <keystore_file> -storepass <keystore_passwd>
# 修改keysore密碼
keytool -storepasswd -new <new_storepasswd> -keystore <keystore_file> -storepass <old_storepasswd>
# 列出信任的CA證書(檢視 JVM的信任庫中的證書,storepass 預設為changeit)
## 該證書檔案存在於JAVA_HOME\jre\lib\security目錄下,是Java系統的CA證書倉庫,可以用 'alias' 來檢視證書是否真的匯入到JVM中
keytool -list -v [-alias clientCer] -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit
# 匯入新的CA到信任證書,匯入到 JRE的信任證書庫
## 常出現的異常:「未找到可信任的證書」 -- 主要原因為在使用者端未將伺服器下發的證書匯入到JVM中。
keytool -import -trustcacerts -alias clientCer -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -file ~/ssl/client.cer
開啟Tomcat_HOME/conf/server.xml,找到如下原註釋內容,並修改如下:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="~/ssl/tomcat.jks" keystorePass="123456"
truststoreFile="~/ssl/truststore.jks" truststorePass="123456"
/>
Tips:
clientAuth
指定是否需要驗證使用者端證書false
: 表示單向SSL驗證,即伺服器端認證;true
: 表示強制雙向SSL驗證,必須驗證使用者端證書;want
: 表示可以驗證使用者端證書,但如果使用者端沒有有效證書,也不強制驗證。p12
檔案將證書匯入至瀏覽器;80
, HTTPS預設埠為 443
;keystoreFile
/keystorePass
: 伺服器證書檔案和密碼;truststoreFile
/truststorePass
: 信任證書檔案和密碼;用來驗證使用者端的。<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="~/ssl/tomcat.jks" keystorePass="123456"()
/>
建立伺服器證書,建立使用者端證書
匯出伺服器公鑰證書,匯出使用者端公鑰證書
將伺服器公鑰證書匯入使用者端(使用者端信任伺服器)
將使用者端公鑰證書匯入信任庫(伺服器信任使用者端)
設定 Tomcat,並開啟雙向認證():
開啟Tomcat_HOME/conf/server.xml,找到如下原註釋內容,並修改如下:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="~/ssl/tomcat.jks" keystorePass="123456"
truststoreFile="~/ssl/truststore.jks" truststorePass="123456"
/>
開啟Tomcat_HOME/conf/web.xml,在 與 加入如下程式碼:
<login-config>
<!-- Authorization setting for SSL -->
<auth-method>CLIENT-CERT</auth-method>
<realm-name>Client Cert Users-only Area</realm-name>
</login-config>
<security-constraint>
<!-- Authorization setting for SSL -->
<web-resource-collection >
<web-resource-name >SSL</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
瀏覽器存取時提示:
此伺服器無法證實它是「192.168..」 - 您計算機的作業系統不信任其安全證書 。。。
--使用者端未匯入伺服器證書
此伺服器無法證實它就是「192.168..」 - 它的安全證書沒有指定主題備用名稱 。。。
--生成伺服器證書庫未使用 -ext引數
「192.168..」不接受您的登入證書,或者您可能沒有提供登入證書。。。
--Tomcat設定未指定信任證書庫(truststore)
Reference