一. 證書
????目前總的來說有三種常用的證書格式:X.509
證書、PKCS#12
證書和PKCS#7
證書。X.509
證書是最經常使用的證書,它僅包含了公鑰信息而沒有私鑰信息,是可以公開進行發(fā)布的,所以X.509
證書對象一般都不需要加密。
1. X.509證書
????X.509是一種證書標準,主要定義了證書中應該包含哪些內容.其詳情可以參考RFC5280,SSL使用的就是這種證書標準。X.509證書的格式通常如下:
……相關的可讀解釋信息(省略)……
---BEGIN CERTIFICATE---
……PEM編碼的X.509證書內容(省略)……
---END CERTIFICATE---
????除了---BEGIN CERTIFICATE---
和---END CERTIFICATE---
頭尾格式外,還可能有這樣不同的標識符:---BEGIN X.509 CERTIFICATE---
、---END X.509 CERTIFICATE---
或者---BEGIN TRUSTED CERTIFICATE---
、---END TRUSTED CERTIFICATE---
????在OpenSSL實際簽發(fā)的證書文件中最前面的很多可讀的證書明文解釋,只是為了增加證書文件的可讀性,并不代表真正的數據。在其他軟件中,比如Windows軟件,可能并不支持這些額外的明文信息,所以,先要將---BEGIN CERTIFICATE---
之前的所有可讀信息去掉。可以手動刪除,也可以使用PEM到PEM的證書格式轉換去掉這些明文可讀信息。在Windows平臺,X.509證書文件的后綴名經常是der、cer或者crt,都是可以被自動識別的。對于OpenSSL來說,后綴名是沒有實際意義的。
2. PKCS#12證書
????PKCS#12
證書不同于X.509
證書,它可以包含一個或多個證書,并且還可以包含證書對應的私鑰。PKCS#12
的私鑰是經過加密的,密鑰由用戶提供的口令產生。所以,無論在使用PKCS#12
證書的時候一般會要用用戶輸入密鑰口令。PKCS#12
證書文件在Windwos
平臺和Mozzila
中支持的后綴名是p12
或者pfx
,如果要在IE
或者Mozzila
中正確使用自己的證書,那么一般來說都要求轉換成包含公鑰和私鑰的PKCS#12
證書導入到相關軟件中。
3. PKCS#7證書
????PKCS#7
可以封裝一個或多個X.509
證書或者PKCS#6
證書(PKCS#6
是一種證書格式,但是并不經常使用)、相關證書鏈上的CA
證書,并且可以包含CRL
信息。PKCS#7
不包含私鑰信息。PKCS#7
可以將驗證證書需要的整個證書上的證書都包含進來,從而方便證書的發(fā)布和正確使用。這樣就可以直接把PKCS#7
證書發(fā)給驗證方驗證,免去了把以上的驗證內容一個一個發(fā)給接書方的煩瑣了。PKCS#7
文件在Windows
平臺的合法后綴名是p7b
。
4. PKCS#8證書
????PKCS#8
標準是一個非常簡單的標準,它主要用于封裝私鑰和其他相關的屬性信息。一般來說,PKCS#8
格式的私鑰都是被加密的,支持PKCS#5
和PKCS#12
標準定義的算法,當然,私鑰也可以不加密。PKCS#8
標準一方面可以增強私鑰的安全性,另一方面也為用戶提供了一種簡單的確立信任關系的方式,這主要是基于私鑰特別名稱和最高層可信者的權威公鑰等屬性信息。OpenSSL
提供的經過PEM
編碼的PKCS#8
標準的文件,分為加密和非加密的兩種方式。加密的PKCS#8
密鑰標識如下:
——BEGIN ENCRYPTED PRIVATE KEY——
——END ENCRYPTED PRIVATE KEY——
????非加密的PKCS#8
密鑰標識如下:
——BEGIN PRIVATE KEY——
——END PRIVATE KEY——
5. Netscape證書
????Netscape
提供了一種名為Netscap
證書序列Netscape Cerificate Sequence
的格式來封裝一系列證書,實際上里面采用了一個PKCS#7
格式來封裝證書。以便能夠一次性地下載或者傳輸多個數字證書。所以,某些時候,Netscape
證書序列可以替代PKCS#7
的作用,用來打包一系列證書。Netscape
證書序列雖然不一定能夠得到微軟的支持,但是在其他一些開源軟件和Linux
軟件中卻得到了廣泛的支持。
6. 其他證書
????證書吊銷列表CRL
是用戶驗證證書的重要參考資料,它主要包含了無效的證書列表,告訴用戶哪些證書已經吊銷或無效的。如果沒有CRL
,可以選擇另一種驗證方式,那就是使用在線證書服務協議OCSP
。OCSP
并不總是能夠使用,比如你的網絡有時候可能不能接通OCSP
服務器。CRL
是一種相對方使用和獨立的解決方案,只要獲取了CA
中心提供的在有效期內的CRL
,基本上就能對證書的有效性進行驗證。PEM
格式編碼的CRL
一般包含在一對符號內:---BEGIN X.509 CRL---
和---END X.509 CRL---
。也可以使用DER
格式保存CRL
。
二. 證書編碼
1. DER
????首先介紹一下ASN.1
標準,全稱:Abstract Syntax Notation One
,這是一種描述數字對象的方法和標準。ASN.1
是一種結構化的數字對象描述語言,它包括兩部分:數據描述語言ISO 8824
和數據編碼規(guī)則ISO 8825
。ASN.1
的數據描述語言允許用戶自定義基本的數據類型,并可以通過簡單的數據類型組成更復雜的數據類型。比如:一個復雜的數據對象,如X.509
證書,就是在其他一些數據類型上定義的,而其他數據類型又是在更基本的數據類型上建立的,直到回溯到定義的最基本的數據類型。ASN.1
提供了多種數據編碼方法。包括了BER
、DER
、PER
和XER
等。這些編碼方法規(guī)定了將數字對象轉換成應用程序能夠處理、保存和網絡傳輸的二進制編碼形式的一組規(guī)則。目前經常被采用的是BER
(Basic Encode Rules
)編碼,但是BER
編碼具有編碼不唯一的性質,也就是說,一個相同的對象通過BER
編碼可能會產生幾種不同的編碼數據。所以,在OpenSSL
和其他密碼學相關軟件中經常使用BER
的一個子集DER
(Distinguished Encoding Rules
)。對于每一個ASN.1
對象,使用DER
編碼得出的二制編碼碼數據是唯一的,Java
和Windows
服務器偏向于使用這種編碼格式。
2. PEM
????PEM
編碼全稱是Privacy Enhanced Mail
,是一種保密郵件的編碼標準。Apache
和*NIX
服務器偏向于使用這種編碼格式。通常來說,對信息的編碼過程基本如下:
- 信息轉換為
ASCII
碼或其他編碼方式,比如采用DER
編碼。 - 使用對稱加密算法加密經過編碼的信息。
- 使用
BASE64
對加密碼后的信息進行編碼。 - 使用一些頭定義對信息進行封裝,主要包含了進行正確解碼需要的信息,頭定義的格式形式如下:
Proc-Type:4,ENCRYPTED
DEK-Info:cipher-name,ivec
????其中,第一個頭信息標注了該文件是否進行了加密,該頭信息可能的值包括ENCRYPTED
(信息已經加密和簽名),MIC-ONLY
(信息經過數據簽名但沒有加密),MIC-CLEAR
(信息經過數字簽名但是沒有加密,也沒有進行編碼,可使用非PEM
格式閱讀),以及CLEAR
;第二個頭信息標注了加密的算法及對稱加密塊算法使用的初始向量。例子:
---BEGIN RSA PRIVATE KEY---
Proc-Type:4,ENCRYPTED
DEK-Info:DES-ED3-CBC,86B0167E005535D2
……(加密內容密鑰部分)……
---END RSA PRIVATE KEY---
????以上的PEM
編碼的是RSA
(RSA PRIVATE KEY
)私鑰,該密鑰經過了加密ENCRYPTED
,使用的是3DES
的CBC
方式(DES-EDE3-CBC
),使用的IV
向量是86B0167E005535D2
。
- 在這些信息的前面加上如下形式頭標注信息:
---BEGIN PRIVACY-ENHANCED MESSAGE---
,在這些信息的后面加上如下形尾標注信息:---END PRIVACY-ENHANCED MESSAGE---
????OpenSSL
的PEM
編碼基本上是基于DER
編碼之上的,也就是說,它在上述第一步采用的是DER
編碼,所以,從本質上來說,OpenSSL
的PEM
編碼就是在DER
編碼基礎上進行BASE64
編碼,然后添加一些頭尾信息組成的。
3. 編碼轉換
# PEM轉為DER
openssl x509 -in cert.crt -outform der -out cert.der
# DER轉為PEM
openssl x509 -in cert.crt -inform der -outform pem -out cert.pem
????要轉換KEY
文件也類似,只不過把x509
換成rsa
,生成CSR
的話,把x509
換成req
三. 常用文件擴展名及其編碼格式
????經過前面的介紹證書可以使用不同的編碼格式進行編碼,這是比較誤導人的地方,雖然我們已經知道有PEM
和DER
這兩種編碼格式,但文件擴展名并不一定就叫PEM
"或者DER
,常見的擴展名除了PEM
和DER
還有以下這些,它們除了編碼格式可能不同之外,內容也有差別,但大多數都能相互轉換編碼格式。
CRT
????CRT
應該是certificate
的三個字母,其實還是證書的意思,常見于*NIX
系統,有可能是PEM
編碼,也有可能是DER
編碼,大多數應該是PEM
編碼,相信你已經知道怎么辨別。
CER
????還是certificate
,常見于Windows
系統,同樣的,可能是PEM
編碼,也可能是DER
編碼,大多數應該是DER
編碼。
KEY
????通常用來存放一個公鑰或者私鑰,不一定是X.509
證書,編碼可能是PEM
,也可能是DER
。查看KEY
的辦法:
openssl rsa -in mykey.key -text -noout
????如果是DER
格式的話,應該這樣了:
openssl rsa -in mykey.key -text -noout -inform der
CSR
????全稱:Certificate Signing Request
,即證書簽名請求,這個并不是證書,而是向權威證書頒發(fā)機構獲得簽名證書的申請,其核心內容是一個公鑰(當然還附帶了一些別的信息),在生成這個申請之前也會生成一個私鑰,私鑰要自己保管好。做過iOS APP
的朋友都應該知道是怎么向蘋果申請開發(fā)者證書的吧。查看的辦法:
openssl req -noout -text -in my.csr (如果是DER格式的話照舊加上-inform der,這里不寫了)
PFX/P12
????predecessor of PKCS#12
,對*nix
服務器來說,一般CRT
和KEY
是分開存放在不同文件中的,但Windows
的IIS
則將它們存在一個PFX
文件中,因此這個文件包含了證書及私鑰,PFX
通常會有一個"提取密碼",你想把里面的東西讀取出來的話,它就要求你提供提取密碼,PFX
使用DER
編碼,如何把PFX
轉換為PEM
編碼,操作如下:
openssl pkcs12 -in for-iis.pfx -out for-iis.pem -nodes
????這個時候會提示你輸入提取密碼,生成pfx
的命令類似這樣:
openssl pkcs12 -export -in certificate.crt -inkey privateKey.key -out certificate.pfx -certfile CACert.crt
????其中CACert.crt
是CA
是權威證書頒發(fā)機構的根證書,通過-certfile
參數一起帶進去。這么看來,PFX
其實是個證書密鑰庫。
JKS
????即Java Key Storage
,這是Java
的專利,跟OpenSSL
關系不大,利用Java
的一個叫keytool
的工具,可以將PFX
轉為JKS
,當然了,keytool
也能直接生成JKS
。