常見的數字證書格式

FrankYou發表於2017-09-15

cer字尾的證照檔案有兩種編碼-->DER二進位制編碼或者BASE64編碼(也就是.pem) 

p7b一般是證照鏈,裡面包括1到多個證照 
pfx是指以pkcs#12格式儲存的證照和相應私鑰。 

在Security程式設計中,有幾種典型的密碼交換資訊檔案格式: 
DER-encoded certificate: .cer, .crt 
PEM-encoded message: .pem 
PKCS#12 Personal Information Exchange: .pfx, .p12 
PKCS#10 Certification Request: .p10 
PKCS#7 cert request response: .p7r 
PKCS#7 binary message: .p7b 

.cer/.crt是用於存放證照,它是2進位制形式存放的,不含私鑰。 
.pem跟crt/cer的區別是它以Ascii來表示。 
pfx/p12用於存放個人證照/私鑰,他通常包含保護密碼,2進位制方式 
p10是證照請求 
p7r是CA對證照請求的回覆,只用於匯入 
p7b以樹狀展示證照鏈(certificate chain),同時也支援單個證照,不含私鑰。 

其中,我介紹如何從p12/pfx檔案中提取金鑰對及其長度: 
1,首先,讀取pfx/p12檔案(需要提供保護密碼) 
2,通過別名(Alias,注意,所有證照中的資訊項都是通過Alias來提取的)提取你想要分析的證照鏈 
3,再將其轉換為一個以X509證照結構體 
4,提取裡面的項,如果那你的證照項放在第一位(單一證照),直接讀取 x509Certs[0](見下面的程式碼)這個X509Certificate物件 
5,X509Certificate物件有很多方法,tain198127網友希望讀取RSA金鑰(公私鑰)及其長度(見http://www.matrix.org.cn/thread.shtml?topicId=43786&forumId=55&#reply),那真是太Easy了, 
            X509Certificate keyPairCert = x509Certs[0]; 
            int iKeySize = X509CertUtil.getCertificateKeyLength(keyPairCert); 
            System.out.println("證照金鑰演算法="+keyPairCert.getPublicKey().getAlgorithm()); 
            System.out.println("證照金鑰長度="+iKeySize); 
提取了他所需要的資訊。 

X.509定義了兩種證照:公鑰證照和屬性證照   
  PKCS#7和PKCS#12使用的都是公鑰證照   
  PKCS#7的SignedData的一種退化形式可以分發公鑰證照和CRL   
  一個SignedData可以包含多張公鑰證照   
  PKCS#12可以包含公鑰證照及其私鑰,也可包含整個證照鏈   

簡介 
Java自帶的keytool工具是個金鑰和證照管理工具。它使使用者能夠管理自己的公鑰/私鑰對及相關證照,用於(通過數字簽名)自我認證(使用者向別的使用者/服務認證自己)或資料完整性以及認證服務。它還允許使用者儲存他們的通訊對等者的公鑰(以證照形式)。 

keytool 將金鑰和證照儲存在一個所謂的金鑰倉庫(keystore)中。預設的金鑰倉庫實現將金鑰倉庫實現為一個檔案。它用口令來保護私鑰。 

Java KeyStore的型別 
JKS和JCEKS是Java金鑰庫(KeyStore)的兩種比較常見型別(我所知道的共有5種,JKS, JCEKS, PKCS12, BKS,UBER)。 

JKS的Provider是SUN,在每個版本的JDK中都有,JCEKS的Provider是SUNJCE,1.4後我們都能夠直接使用它。 

JCEKS在安全級別上要比JKS強,使用的Provider是JCEKS(推薦),尤其在保護KeyStore中的私鑰上(使用TripleDes)。 

PKCS#12是公鑰加密標準,它規定了可包含所有私鑰、公鑰和證照。其以二進位制格式儲存,也稱為 PFX 檔案,在windows中可以直接匯入到金鑰區,注意,PKCS#12的金鑰庫保護密碼同時也用於保護Key。 

BKS 來自BouncyCastle Provider,它使用的也是TripleDES來保護金鑰庫中的Key,它能夠防止證照庫被不小心修改(Keystore的keyentry改掉1個 bit都會產生錯誤),BKS能夠跟JKS互操作,讀者可以用Keytool去TryTry。 

UBER比較特別,當密碼是通過命令列提供的時候,它只能跟keytool互動。整個keystore是通過PBE/SHA1/Twofish加密,因此keystore能夠防止被誤改、察看以及校驗。以前,Sun JDK(提供者為SUN)允許你在不提供密碼的情況下直接載入一個Keystore,類似cacerts,UBER不允許這種情況。 

證照匯入 
Der/Cer證照匯入: 

要從某個檔案中匯入某個證照,使用keytool工具的-import命令: 

keytool -import -file mycert.der -keystore mykeystore.jks 

如果在 -keystore 選項中指定了一個並不存在的金鑰倉庫,則該金鑰倉庫將被建立。 

如果不指定 -keystore 選項,則預設金鑰倉庫將是宿主目錄中名為 .keystore 的檔案。如果該檔案並不存在,則它將被建立。 

建立金鑰倉庫時會要求輸入訪問口令,以後需要使用此口令來訪問。可使用-list命令來檢視金鑰倉庫裡的內容: 

keytool -list -rfc -keystore mykeystore.jks 

P12格式證照匯入: 

keytool無法直接匯入PKCS12檔案。 

第一種方法是使用IE將pfx證照匯入,再匯出為cert格式檔案。使用上面介紹的方法將其匯入到金鑰倉庫中。這樣的話倉庫裡面只包含了證照資訊,沒有私鑰內容。 


第二種方法是將pfx檔案匯入到IE瀏覽器中,再匯出為pfx檔案。 
       新生成的pfx不能被匯入到keystore中,報錯:keytool錯誤: java.lang.Exception: 所輸入的不是一個 X.509 認證。新生成的pfx檔案可以被當作keystore使用。但會報個錯誤as unknown attr1.3.6.1.4.1.311.17.1,查了下資料,說IE匯出的就會這樣,使用Netscape就不會有這個錯誤. 

第三種方法是將pfx檔案當作一個keystore使用。但是通過微軟的證照管理控制檯生成的pfx檔案不能直接使用。keytool不認此格式,報keytool錯誤: java.io.IOException: failed to decrypt safe contents entry。需要通過OpenSSL轉換一下: 

1)openssl pkcs12 -in mycerts.pfx -out mycerts.pem 

2)openssl pkcs12 -export -in mycerts.pem -out mykeystore.p12 

通過keytool的-list命令可檢查下金鑰倉庫中的內容: 

keytool -rfc -list -keystore mykeystore.p12 -storetype pkcs12 

這裡需要指明倉庫型別為pkcs12,因為預設的型別為jks。這樣此金鑰倉庫就即包含證照資訊也包含私鑰資訊。 

P7B格式證照匯入: 

keytool無法直接匯入p7b檔案。 

需要將證照鏈RootServer.p7b(包含根證照)匯出為根rootca.cer和子rootcaserver.cer 。 

將這兩個證照匯入到可信任的金鑰倉庫中。 

keytool -import -alias rootca -trustcacerts -file rootca.cer -keystore testkeytrust.jks 

遇到是否信任該證照提示時,輸入y 

keytool -import -alias rootcaserver -trustcacerts -file rootcaserver.cer -keystore testkeytrust.jks 

相關文章