一、什么是證書、為什么要引用證書
對數據進行簽名(加密)是我們在網絡中最常見的安全操作。簽名有雙重作用,作用一就是保證數據的完整性,證明數據並非偽造,而且在傳輸的過程中沒有被篡改,作用二就是防止數據的發布者否認其發布了該數據。
簽名同時使用了非對稱性加密算法和消息摘要算法,對一塊數據簽名時,會先對這塊數據進行消息摘要運算生成一個摘要,然后對該摘要使用發布者的私鑰進行加密。 比如微信公眾平台開發中最常見的調用api接口方法是將參數進行字典序排序,然后將參數名和參數值接成一個字符串,組合的字符串也就相當於我們這里說的摘要,然后將摘要用平台密鑰加密。接收者(客戶端)接受到數據后,先使用發布者的公鑰進行解密得到原數據的摘要,再對接收到的數據計算摘要,如果兩個摘要相同,則說明數據沒有被篡改。同時,因為發布者的私鑰是不公開的,只要接收者通過發布者的公鑰能成功對數據進行解密,就說明該數據一定來源於該發布者。那么怎么確定某公鑰一定是屬於某發布者的呢?這就需要證書了。證書由權威認證機構頒發,其內容包含證書所有者的標識和它的公鑰,並由權威認證機構使用它的私鑰進行簽名。信息的發布者通過在網絡上發布證書來公開它的公鑰,該證書由權威認證機構進行簽名,認證機構也是通過發布它的證書來公開該機構的公鑰,認證機構的證書由更權威的認證機構進行簽名,這樣就形成了證書鏈。證書鏈最頂端的證書稱為根證書,根證書就只有自簽名了。總之,要對網絡上傳播的內容進行簽名和認證,就一定會用到證書。關於證書遵循的標准,最流行的是 X.509。
二、證書生成與管理(基於keytool)
JDK中keytool常用參數說明(不同版本有差異,詳細可參見【附錄】中的官方文檔鏈接):
-genkey 在用戶主目錄 -genkey 在用戶主目錄中創建一個默認文件”.keystore”,還會產生一個mykey的別名,mykey中包含用戶的公鑰、私鑰和證書(在沒有指定生成位置的情況下,keystore會存在用戶系統默認目錄) -alias 產生別名 每個keystore都關聯這一個獨一無二的alias,這個alias通常不區分大小寫 -keystore 指定密鑰庫的名稱(產生的各類信息將不在.keystore文件中) -keyalg 指定密鑰的算法 (如 RSA DSA,默認值為:DSA) -validity 指定創建的證書有效期多少天(默認 90) -keysize 指定密鑰長度 (默認 1024) -storepass 指定密鑰庫的密碼(獲取keystore信息所需的密碼) -keypass 指定別名條目的密碼(私鑰的密碼) -dname 指定證書發行者信息 其中: “CN=名字與姓氏,OU=組織單位名稱,O=組織名稱,L=城市或區域名 稱,ST=州或省份名稱,C=單位的兩字母國家代碼” -list 顯示密鑰庫中的證書信息 keytool -list -v -keystore 指定keystore -storepass 密碼 -v 顯示密鑰庫中的證書詳細信息 -export 將別名指定的證書導出到文件 keytool -export -alias 需要導出的別名 -keystore 指定keystore -file 指定導出的證書位置及證書名稱 -storepass 密碼 -file 參數指定導出到文件的文件名 -delete 刪除密鑰庫中某條目 keytool -delete -alias 指定需刪除的別 -keystore 指定keystore – storepass 密碼 -printcert 查看導出的證書信息 keytool -printcert -file g:\sso\michael.crt -keypasswd 修改密鑰庫中指定條目口令 keytool -keypasswd -alias 需修改的別名 -keypass 舊密碼 -new 新密碼 -storepass keystore密碼 -keystore sage -storepasswd 修改keystore口令 keytool -storepasswd -keystore g:\sso\michael.keystore(需修改口令的keystore) -storepass pwdold(原始密碼) -new pwdnew(新密碼) -import 將已簽名數字證書導入密鑰庫 keytool -import -alias 指定導入條目的別名 -keystore 指定keystore -file 需導入的證書 中創建一個默認文件”.keystore”,還會產生一個mykey的別名,mykey中包含用戶的公鑰、私鑰和證書(在沒有指定生成位置的情況下,keystore會存在用戶系統默認目錄) -alias 產生別名 每個keystore都關聯這一個獨一無二的alias,這個alias通常不區分大小寫 -keystore 指定密鑰庫的名稱(產生的各類信息將不在.keystore文件中) -keyalg 指定密鑰的算法 (如 RSA DSA,默認值為:DSA) -validity 指定創建的證書有效期多少天(默認 90) -keysize 指定密鑰長度 (默認 1024) -storepass 指定密鑰庫的密碼(獲取keystore信息所需的密碼) -keypass 指定別名條目的密碼(私鑰的密碼) -dname 指定證書發行者信息 其中: “CN=名字與姓氏,OU=組織單位名稱,O=組織名稱,L=城市或區域名 稱,ST=州或省份名稱,C=單位的兩字母國家代碼” -list 顯示密鑰庫中的證書信息 keytool -list -v -keystore 指定keystore -storepass 密碼 -v 顯示密鑰庫中的證書詳細信息 -export 將別名指定的證書導出到文件 keytool -export -alias 需要導出的別名 -keystore 指定keystore -file 指定導出的證書位置及證書名稱 -storepass 密碼 -file 參數指定導出到文件的文件名 -delete 刪除密鑰庫中某條目 keytool -delete -alias 指定需刪除的別 -keystore 指定keystore – storepass 密碼 -printcert 查看導出的證書信息 keytool -printcert -file g:\sso\michael.crt -keypasswd 修改密鑰庫中指定條目口令 keytool -keypasswd -alias 需修改的別名 -keypass 舊密碼 -new 新密碼 -storepass keystore密碼 -keystore sage -storepasswd 修改keystore口令 keytool -storepasswd -keystore g:\sso\michael.keystore(需修改口令的keystore) -storepass pwdold(原始密碼) -new pwdnew(新密碼) -import 將已簽名數字證書導入密鑰庫 keytool -import -alias 指定導入條目的別名 -keystore 指定keystore -file 需導入的證書
三、使用keytool工具創建證書
a、創建證書yunbo.keystore文件
keytool -genkey -alias "yunBo" -keyalg "RSA" -keystore "d:\jkstest\yunbo.keystore" -dname "CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN" -keypass "123456" -storepass "changeit" -validity 180
b、對應命令解釋
-genkey 表示要創建一個新的密鑰
-dname 表示密鑰的Distinguished Names, 表明了密鑰的發行者身份
CN=commonName 注:生成證書時,CN要和服務器的域名相同,如果在本地測試,則使用localhost
OU=organizationUnit
O=organizationName
L=localityName
S=stateName
C=country
-keyalg 使用加密的算法,這里是RSA
-alias 和keystore關聯的別名,這個alias通常不區分大小寫
-keypass 私有密鑰的密碼,這里設置為 123456
-keystore 密鑰保存在D:盤目錄下的yunbo.keystore文件中
-storepass 存取密碼,這里設置為changeit,這個密碼提供系統從yunbo.keystore文件中將信息取出
-validity 該密鑰的有效期為 180天 (默認為90天)
-alias "mykey" -keyalg "DSA" -keysize 1024 -validity 90 -keystore 用戶宿主目錄中名為 .keystore 的文件 -file 讀時為標准輸入,寫時為標准輸出
cacerts證書文件(The cacerts Certificates File)
該證書文件存在於java.home\jre\lib\security目錄下,是Java系統的CA證書倉庫
導出證書給客戶端安裝
客戶端配置:為客戶端的JVM導入密鑰(將服務器下發的證書導入到JVM中)
生成的證書可以交付客戶端用戶使用,用以進行SSL通訊,或者伴隨電子簽名的jar包進行發布者的身份認證。常出現的異常:“未找到可信任的證書”--主要原因為在客戶端未將服務器下發的證書導入到JVM中,可以用
生成的證書可以交付客戶端用戶使用,用以進行SSL通訊,或者伴隨電子簽名的jar包進行發布者的身份認證。
常出現的異常:“未找到可信任的證書”--主要原因為在客戶端未將服務器下發的證書導入到JVM中,
可以用 keytool -list -alias yunbo -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -storepass changeit 來查看證書是否真的導入到JVM中。
yunbo, 2018-9-23, trustedCertEntry, 證書指紋 (SHA1): BF:7E:C3:07:03:EA:41:50:02:B9:C7:15:38:54:BF:80:01:D1:1D:D5
要導出證書庫里面的某個證書,可以使用如下命令
keytool -export -keystore cacerts -storepass 666666 -alias yunbo -file d:/jkstest/yunbo.cer
keytool -export -alias yunbo -keystore e:/server.jks -file d:/jkstest/yunbo.crt -rfc -storepass changeit
*備注: keystore.jks 也可以為 .keystore格式 ; server.crt也可以為 .cer格式 "-rfc" 表示以base64輸出文件,否則以二進制輸出
要修改某個證書的密碼(注意:有些數字認證沒有私有密碼,只有公匙,這種情況此命令無效)
修改別名:
keytool -changealias -keystore mykeystore.keystore -alias 當前別名 -destalias 新別名
主流數字證書都有哪些格式
一般來說,主流的Web服務軟件,通常都基於OpenSSL和Java兩種基礎密碼庫。
- Tomcat、Weblogic、JBoss等Web服務軟件,一般使用Java提供的密碼庫。通過Keytool工具,生成Java Keystore(JKS)格式的證書文件。
- Apache、Nginx等Web服務軟件,一般使用OpenSSL工具提供的密碼庫,生成PEM、KEY、CRT等格式的證書文件。
- IBM的Web服務產品,如Websphere、IBM Http Server(IHS)等,一般使用IBM產品自帶的iKeyman工具,生成KDB格式的證書文件。
- 微軟Windows Server中的Internet Information Services(IIS)服務,使用Windows自帶的證書庫生成PFX格式的證書文件。
判斷證書文件是文本格式還是二進制格式
您可以使用以下方法簡單區分帶有后綴擴展名的證書文件:
- *.DER或*.CER文件: 這樣的證書文件是二進制格式,只含有證書信息,不包含私鑰。
- *.CRT文件: 這樣的證書文件可以是二進制格式,也可以是文本格式,一般均為文本格式,功能與 *.DER及*.CER證書文件相同。
- *.PEM文件: 這樣的證書文件一般是文本格式,可以存放證書或私鑰,或者兩者都包含。 *.PEM 文件如果只包含私鑰,一般用*.KEY文件代替。
- *.PFX或*.P12文件: 這樣的證書文件是二進制格式,同時包含證書和私鑰,且一般有密碼保護。
您也可以使用記事本直接打開證書文件。如果顯示的是規則的數字字母,例如:
—–BEGIN CERTIFICATE—–
MIIE5zCCA8+gAwIBAgIQN+whYc2BgzAogau0dc3PtzANBgkqh......
—–END CERTIFICATE—–
那么,該證書文件是文本格式的。
- 如果存在
——BEGIN CERTIFICATE——
,則說明這是一個證書文件。 - 如果存在
—–BEGIN RSA PRIVATE KEY—–
,則說明這是一個私鑰文件
證書格式之間的轉換如下圖:
Note: 阿里雲雲盾證書服務統一使用 PEM 格式的數字證書文件。
-
將JKS格式證書轉換成PFX格式
您可以使用JDK中自帶的Keytool工具,將JKS格式證書文件轉換成PFX格式。例如,您可以執行以下命令將server.jks證書文件轉換成server.pfx證書文件:
keytool -importkeystore -srckeystore D:\server.jks -destkeystore D:\server.pfx -srcstoretype JKS -deststoretype PKCS12
-
將PFX格式證書轉換為JKS格式
您可以使用JDK中自帶的Keytool工具,將PFX格式證書文件轉換成JKS格式。例如,您可以執行以下命令將server.pfx證書文件轉換成server.jks證書文件:
keytool -importkeystore -srckeystore D:\server.pfx -destkeystore D:\server.jks -srcstoretype PKCS12 -deststoretype JKS
-
將PEM/KEY/CRT格式證書轉換為PFX格式
您可以使用 OpenSSL工具,將KEY格式密鑰文件和CRT格式公鑰文件轉換成PFX格式證書文件。例如,將您的KEY格式密鑰文件(server.key)和CRT格式公鑰文件(server.crt)拷貝至OpenSSL工具安裝目錄,使用OpenSSL工具執行以下命令將證書轉換成server.pfx證書文件:
openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt
-
將PFX轉換為PEM/KEY/CRT
可以使用 OpenSSL工具,將PFX格式證書文件轉化為KEY格式密鑰文件和CRT格式公鑰文件。例如,將您的PFX格式證書文件拷貝至OpenSSL安裝目錄,使用OpenSSL工具執行以下命令將證書轉換成server.pem證書文件,KEY格式密鑰文件(server.key)和CRT格式公鑰文件(server.crt):
openssl pkcs12 -in server.pfx -nodes -out server.pem
openssl rsa -in server.pem -out server.key
openssl x509 -in server.pem -out server.crt
Note: 此轉換步驟是專用於通過Keytool工具生成私鑰和CSR申請證書文件的,並且通過此方法您可以在獲取到PEM格式證書公鑰的情況下分離私鑰。
(Java、.Net、Php)語言需要的證書格式並不一致,比如說Java我們采用jks,.Net采用pfx和cer,Php則采用pem和cer;
主要分成兩類,其一為密鑰庫文件格式、其二為證書文件格式;
密鑰庫文件格式【Keystore】
格式 | 擴展名 | 描述 | 特點 |
JKS |
.jks/.ks |
【Java Keystore】密鑰庫的Java實現版本,provider為SUN |
密鑰庫和私鑰用不同的密碼進行保護 |
JCEKS |
.jce |
【JCE Keystore】密鑰庫的JCE實現版本,provider為SUN JCE |
相對於JKS安全級別更高,保護Keystore私鑰時采用TripleDES |
PKCS12 |
.p12/.pfx |
【PKCS #12】個人信息交換語法標准 |
1、包含私鑰、公鑰及其證書 |
BKS |
.bks |
【Bouncycastle Keystore】密鑰庫的BC實現版本,provider為BC |
基於JCE實現 |
UBER |
.ubr |
【Bouncycastle UBER Keystore】密鑰庫的BC更安全實現版本,provider為BC |
|
證書文件格式【Certificate】
格式 | 擴展名 | 描述 | 特點 |
DER | .cer/.crt/.rsa | 【ASN .1 DER】用於存放證書 | 不含私鑰、二進制 |
PKCS7 | .p7b/.p7r | 【PKCS #7】加密信息語法標准 | 1、p7b以樹狀展示證書鏈,不含私鑰 2、p7r為CA對證書請求簽名的回復,只能用於導入 |
CMS | .p7c/.p7m/.p7s | 【Cryptographic Message Syntax】 | 1、p7c只保存證書 |
PEM | .pem | 【Printable Encoded Message】 | 1、該編碼格式在RFC1421中定義,其實PEM是【Privacy-Enhanced Mail】的簡寫,但他也同樣廣泛運用於密鑰管理 2、ASCII文件 3、一般基於base 64編碼 |
PKCS10 | .p10/.csr | 【PKCS #10】公鑰加密標准【Certificate Signing Request】 | 1、證書簽名請求文件 2、ASCII文件 3、CA簽名后以p7r文件回復 |
SPC | .pvk/.spc | 【Software Publishing Certificate】 | 微軟公司特有的雙證書文件格式,經常用於代碼簽名,其中 1、pvk用於保存私鑰 2、spc用於保存公鑰 |
1、Java平台keytool對X.509證書的支持並不一致,6.0版本之前生成的證書都是v1版本的,這在很多應用場合可能會導致一些潛在的問題,但是他還是能夠管理v3版本的證書的,從6.0開始keytool支持v3版本的證書生成;
2、Eclipse插件SecureX推薦,這是一個國人貢獻的證書生成、管理工具,效果還是不錯的,而且可以下載源代碼查看,對學習Security方面的編程很有幫助,可以從http://securex.sourceforge.net/updatesite更新,目前版本為2.0,不過好像現在作者也沒有更新了;
3、KeyTool IUI工具推薦,這是一個老外編寫的Keytool GUI工具,功能大致和SecureX類似,他可以以application或者Java Web Start啟動查看,但作者並沒有提供源代碼下載,首頁為http://yellowcat1.free.fr/keytool_iui.html;
4、https://www.chinassl.net/ssltools/keytool-commands.html 常用的Java Keytool Keystore命令