一: 什么是證書?為什么要使用證書?
對數據進行簽名(加密)是我們在網絡中最常見的安全操作。簽名有雙重作用,作用一就是保證數據的完整性,證明數據並非偽造,而且在傳輸的過程中沒有被篡改,作用二就是防止數據的發布者否認其發布了該數據。
簽名同時使用了非對稱性加密算法和消息摘要算法,對一塊數據簽名時,會先對這塊數據進行消息摘要運算生成一個摘要,然后對該摘要使用發布者的私鑰進行加密。 比如微信公眾平台開發中最常見的調用api接口方法是將參數進行字典序排序,然后將參數名和參數值接成一個字符串,組合的字符串也就相當於我們這里說的摘要,然后將摘要用平台密鑰加密。
接收者(客戶端)接受到數據后,先使用發布者的公鑰進行解密得到原數據的摘要,再對接收到的數據計算摘要,如果兩個摘要相同,則說明數據沒有被篡改。同時,因為發布者的私鑰是不公開的,只要接收者通過發布者的公鑰能成功對數據進行解密,就說明該數據一定來源於該發布者。
那么怎么確定某公鑰一定是屬於某發布者的呢?這就需要證書了。證書由權威認證機構頒發,其內容包含證書所有者的標識和它的公鑰,並由權威認證機構使用它的私鑰進行簽名。信息的發布者通過在網絡上發布證書來公開它的公鑰,該證書由權威認證機構進行簽名,認證機構也是通過發布它的證書來公開該機構的公鑰,認證機構的證書由更權威的認證機構進行簽名,這樣就形成了證書鏈。證書鏈最頂端的證書稱為根證書,根證書就只有自簽名了。總之,要對網絡上傳播的內容進行簽名和認證,就一定會用到證書。關於證書遵循的標准,最流行的是 X.509
二:證書管理
Keytool是一個Java數據證書的管理工具,這個工具一般在 JDK\jre\bin\security\目錄下 。所有的數字證書是以一條一條(采用別名區別)的形式存入證書庫的中,證書庫中的每個證書包含該條證書的私鑰,公鑰和對應的數字證書的信息。
證書庫中的一條證書可以導出數字證書文件,數字證書文件只包括主體信息和對應的公鑰
Keytool將密鑰(key)和證書(certificates)存在一個稱為keystore的文件中
在keystore里,包含兩種數據:
密鑰實體(Key entity)— 密鑰(secret key)又或者是私鑰和配對公鑰(采用非對稱加密)
可信任的證書實體(trusted certificate entries)— 只包含公鑰
1. 創建證書
keytool -genkeypair -alias "tomcat" -keyalg "RSA" -keystore "d:\mykeystore.keystore" -dname "CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN" -keypass "123456" -storepass -validity 180
參數說明:
-genkeypair 表示要創建一個新的密鑰
-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:盤目錄下的mykeystore文件中
-storepass 存取密碼,這里設置為changeit,這個密碼提供系統從mykeystore文件中將信息取出
-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證書倉庫
2.導出證書,由客戶端安裝
keytool -export -alias tomcat -keystore d:\mykeystore -file d:\mycerts.cer -storepass 123456
3.客戶端配置:為客戶端的JVM導入密鑰(將服務器下發的證書導入到JVM中)
keytool -import -trustcacerts -alias tomcat -keystore "%JAVA_HOME%/jre/lib/security/cacerts " -file d:\mycerts.cer -storepass 123456
生成的證書可以交付客戶端用戶使用,用以進行SSL通訊,或者伴隨電子簽名的jar包進行發布者的身份認證。
常出現的異常:“未找到可信任的證書”--主要原因為在客戶端未將服務器下發的證書導入到JVM中,可以用
keytool -list -alias tomcat -keystore "$JAVA_HOME/jre/lib/security/cacerts" -storepass 123456
來查看證書是否真的導入到JVM中。
keytool生成根證書時出現如下錯誤:
keytool錯誤:java.io.IOException:keystore was tampered with,or password was incorrect
原因是在你的home目錄下是否還有.keystore存在。如果存在那么把他刪除掉,然后再執行或者刪除"%JAVA_HOME%/jre/lib/security/cacerts 再執行
"-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;
主要分成兩類,其一為密鑰庫文件格式、其二為證書文件格式;
密鑰庫文件格式
秘鑰庫概念:所有的公鑰和私鑰同證書都會被存儲在密鑰庫中 因為證書需要被簽名, 簽名必須使用非對稱加密算法+HASH算法 所以一般是MD5WithRSA或者SHA1WithRSA
格式 | 擴展名 | 描述 | 特點 |
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用於保存公鑰 |
證書格式轉換工具介紹
目前兩大開發平台Java和.Net都提供了相關的證書管理工具,
Java是keytool,參考http://java.sun.com/javase/6/docs/technotes/tools/windows/keytool.html;
.Net為makecert,參考http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/cptools/html/cpgrfcertificatecreationtoolmakecertexe.asp;
但是兩者遵循的標准並不是完全兼容,有很多都是基於自己的實現,所以很多的文件格式並不通用,在實際開發使用過程中我們可能需要進行格式轉換,
在轉換過程中,常見格式的轉換可以運用keytool或者是windows證書管理導入導出工具;
另外一個很有用的工具就是OpenSSL,首頁地址為http://www.openssl.org/,各種格式間的轉換示例這里就不提供了
這里要提一些注意事項和小工具:
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;
https原理: http://blog.jobbole.com/110354/