1. 程式人生 > >X.509證書的讀取操作與分析(Java版)

X.509證書的讀取操作與分析(Java版)

文章目錄

X.509證書的讀取操作與分析

1. X.509

該部分所使用知識均來自於維基百科CSDN

1.1 定義

X.509 是密碼學裡公鑰證書的格式標準。

X.509 證書己應用在包括 TLS/SSL在內的眾多 Intenet 協議裡.同時它也用在很多非線上應用場景裡,比如電子簽名服務。

X.509證書裡含有公鑰、身份資訊(比如網路主機名,組織的名稱或個體名稱等)和簽名信息(可以是證書籤發機構CA的簽名,也可以是自簽名)。對於一份經由可信的證書籤發機構簽名或者可以通過其它方式驗證的證書,證書的擁有者就可以用證書及相應的私鑰來建立安全的通訊,對文件進行數字簽名.

另外除了證書本身功能,X.509還附帶了證書吊銷列表和用於從最終對證書進行簽名的證書籤發機構直到最終可信點為止的證書合法性驗證演算法。

1.2 組成結構

  • 證書

    • 版本號

      • 作用:【標識證書的版本(版本1、版本2、或是版本3)】
    • 序列號

      • 作用:【標識證書的唯一整數,由證書頒發者分配的本證書的唯一識別符號】
    • 簽名演算法

      • 作用:【由於簽名書的演算法標識,由物件識別符號加上相關的引數組成,用於說明本證書所用的數字簽名演算法。例如,SHA-1 和 RSA 的物件識別符號就用來說明該數字簽名是利用 RSA 對SHA-1 雜湊加密】
    • 頒發者

      • 作用:【證書頒發者的可識別名】
    • 證書有效期

      • 作用:【證書的有效期時間段】
        • “Not Before” 此日期前無效
        • “Not After” 此日期後有效
        • 以上二者分別由 UTC時間或一般的時間表示
    • 主體

      • 作用:【證書擁有者的可識別名,這個欄位必須是非空的,除非你在證書擴充套件中有別名】
    • 主體公鑰資訊

      • 作用:【標識主題的公鑰以及演算法識別符號】
        • 公鑰演算法
        • 主題公鑰
    • 頒發者唯一身份資訊(可選項)

      • 作用:證書頒發者的唯一識別符號,僅在版本 2 與版本 3 中有要求,屬於可選項
    • 主題唯一身份資訊

      • 作用:證書擁有者的唯一識別符號,僅在版本 2 和版本 3 中有要求,屬於可選項
    • 擴充套件資訊 (次重點部分

      • 發行者祕鑰識別符號

        • 作用:【證書所含金鑰的唯一識別符號,用來區分同一證書擁有者的多對金鑰】
      • 祕鑰使用

        • 作用:【一個位元串,指明(限定)證書的公鑰可以完成的功能或服務,如:證書籤名、資料加密等。

          如果某一證書將 KeyUsage 擴充套件標記為“極重要”,而且設定為“keyCertSign”,則在 SSL 通訊期間該證書出現時將被拒絕,因為該證書擴充套件表示相關私鑰應只用於簽寫證書,而不應該用於 SSL。】

      • CRL 分佈點

        • 作用:【指明 CRL 的分佈地點】
      • 私鑰的使用期

        • 作用:【指明證書中與公鑰相聯絡的私鑰的使用期限,它也由 “ Not Before “ 和" Not After "組成。若此項不存在時,公私鑰的使用期是一樣的】
      • 證書策略

        • 作用:【由物件識別符號和限定符組成,這些物件識別符號說明證書的頒發和使用策略有關】
      • 策略對映

        • 作用:【表明兩個 CA 域之間的一個或多個策略物件識別符號的等價關係,僅在 CA 證書裡存在】
      • 主體別名

        • 作用:【指出證書擁有者的別名,如電子郵件地址、IP 地址等,別名是和 DN 繫結在一起的】
      • 頒發者別名

        • 作用:【指出證書頒發者的別名,如電子郵件地址、IP地址等,但頒發者的 DN 必須出現在證書的頒發者欄位】
      • 主體目錄屬性

        • 作用:【指出證書擁有者的一系列屬性。可以使用這一項來傳遞訪問控制資訊】
  • 證書籤名演算法

  • 數字簽名

1.3 安全性

  • 採用黑名單方式的證書吊銷列表 CRL 和線上證書狀態協議( OCSP )
    • 如果客戶端僅信任在CRL可用的時候信任證書,那就失去離線信任的需求。因此通常客戶端會在CRL不可用的情況下信任證書,因而給了那些可以控制通道的攻擊者可乘之機。如谷歌的Adam Langley所說,對CRL的檢查有如你期望安全帶在出事故事一定能正常使用的
  • 在大範圍及複雜的分佈模式下選用CRL並不明智
  • OCSP由於沒有吊銷狀態的歷史記錄也會出現歧義
  • 聚合問題
  • 代表問題: 證書頒發機構事沒辦法限制其下屬頒發的證書作出名字及屬性方面的限制。而且在Internet上存在著相當多的證書頒發機構,想對他們進行分類和策略上的限制是一項不可能完成的任務。
  • 分佈問題: 證書鏈引的下屬頒發機構,橋接頒發機構以及交叉認證使得證書驗證變得非常複雜,需要付出很大的代價。層次式的第三方信任模型作為一種唯一的模型的話,路徑驗證也可能出現含糊不明的情況岐義,這對於已經建立雙邊信任也很不方便。
  • 釋出一個對主機名的擴充套件驗證並不能防止再發佈一個驗證要求低一些的適用於同一個主機名的證書。這就造成了不能對中間人攻擊的有效保護

1.4 證書檔名擴充套件型別

X.509有多種常用的副檔名。不過其中的一些還用於其它用途,就是說具有這個副檔名的檔案可能並不是證書,比如說可能只是儲存了私鑰。

  • .pem– (隱私增強型電子郵件) DER編碼的證書再進行 Base64 編碼的資料存放在"-----BEGIN CERTIFICATE-----“和”-----END CERTIFICATE-----"之中
  • .cer, .crt, .der – 通常是DER二進位制格式的,但 Base64 編碼後也很常見。
  • .p7b, .p7cPKCS#7
    • 注:PKCS#7 是簽名或加密資料的格式標準,官方稱之為容器。由於證書是可驗真的簽名資料,所以可以用 SignedData 結構表述。
    • 注:P7C檔案是退化的 SignedData 結構,沒有包括簽名的資料。
  • .p12PKCS#12格式,包含證書的同時可能還有帶密碼保護的私鑰
    • 注:PKCS#12PFX 進化而來的用於交換公共的和私有的物件的標準格式。
  • .pfxPFX,PKCS#12之前的格式(通常用 PKCS#12 格式,比如那些由 IIS 產生的 PFX 檔案)

2. 讀取操作程式

2.1 程式語言選擇

語言:Java

選擇原因:

  • 一開始打算用 c++ 實現,使用 c++ 內建的二進位制讀寫函式完成對檔案證書的讀取,隨後再寫一些函式進行操作,但是後來發現讀取時候, c++ 庫檔案並不支援讀取 .cer 型別的檔案讀取,採用斷點除錯才發現問題,程式進入這一步,直接就執行錯誤強行中斷;搜尋了一些資料之後,發現要是想使用 c++ 進行操作,還得需要做很多其他的操作,過程太過於繁瑣,所以就放棄了繼續使用 c++
  • 隨後向已經實習的師兄求助,他讓我去搜索了 JavaCertificateFactory類方法,然後我自己去簡單查閱了一下檔案,發現確實是 Java 中有現成的對 X.509證書進行操作的很多函式,包括讀寫以及對某一項資料的輸出等,所以最後就選擇了使用 Java 語言;並且在讀入X.509證書之後不會再出現亂碼跟程式崩潰的情況了;
  • 在撰寫這次實驗報告時候,也是把自己在學習X509時候的資料都放了進來,進行了一次系統整理,方便自己在期末進行復習

2.2 編譯環境

作業系統: windows 10

條件:

  • 安裝最新版 jre、jdk
  • 配置環境變數
  • 編譯 javac X509.java
  • 執行 java X509

2.3 Security 方法

參考連結

2.4 Security.cert 方法

參考連結

2.5 Security.cert.CrtificateFactory 方法

public class CertificateFactory extends Object

此類定義了用於從相關的編碼中生成證書、證書路徑 (CertPath) 和證書撤消列表 (CRL) 物件的 CertificateFactory 功能。

為了實現多個證書組成的編碼,如果要解析一個可能由多個不相關證書組成的集合時,應使用generateCertificates。否則,如果要生成 CertPath(證書鏈)並隨後使用 CertPathValidator 驗證它,則應使用 generateCertPath

(X.509 的 CertificateFactory 返回的證書必須是 java.security.cert.X509Certificate 的例項)

以下示例程式碼解析一個儲存在檔案中的 PKCS#7 格式的證書答覆,並從中提取所有的證書:

FileInputStream fis = new FileInputStream(filename);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
 Collection c = cf.generateCertificates(fis);
 Iterator i = c.iterator();
 while (i.hasNext()) {
    Certificate cert = (Certificate)i.next();
    System.out.println(cert);
 }

2.6 獲取對應資料

在 2.5 中已經成功的建立一個 X509Certificate型別的物件,接著我們要做的就是讀取到對應的資料,所用的函式方法部分如下表所示:

在這裡插入圖片描述

System.out.println("輸出證書資訊:\n" + s ) ;
System.out.println("版本號:" + t.getVersion()) ;
System.out.println("序列號:" + t.getSerialNumber().toString(16)) ;
System.out.println("簽發者:"+ t.getIssuerDN()) ;
System.out.println("有效起始日期:"+ t.getNotBefore()) ;
System.out.println("有效終止日期:"+ t.getNotAfter()) ;
System.out.println("主體名:"+t.getSubjectDN()) ;
System.out.println("簽名演算法:"+t.getSigAlgName()) ;
System.out.println("簽名:"+t.getSignature().toString()) ;
.....

3. 執行結果

3.1 編譯時遇到的問題與解決方案

3.1.1 字元編碼問題

由於在println使用了部分中文字元輸出,所以在第一次進行編譯時候出現如下錯誤:

在這裡插入圖片描述

解決方案:

編譯時候使用:javac -encoding UTF-8 .\X509.java指令將字元進行轉

3.1.2 異常處理丟擲問題

由於使用了 factory 型別的資料,我們要防止證書過期同時也要保證 IO 操作的正確性,所以需要加上錯誤捕捉,讓程式可以在異常出現時直接退出;

錯誤如圖:

在這裡插入圖片描述

解決方案:

在 main 函式加上異常處理:

在這裡插入圖片描述

在這裡插入圖片描述


3.2 程式執行

3.2.1 隨機證書生成

參考連結

在上述連結中生成的X509證書如下:

-----BEGIN CERTIFICATE-----
MIIDPTCCAiegAwIBAgIBATALBgkqhkiG9w0BAQUwHjEcMAkGA1UEBhMCUlUwDwYD
VQQDHggAVABlAHMAdDAeFw0xNjAxMzExNjAwMDBaFw0xOTAxMzExNjAwMDBaMB4x
HDAJBgNVBAYTAlJVMA8GA1UEAx4IAFQAZQBzAHQwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQDqbF/+iB4WbqzNs5+VeI38O8JIqpQVlSlTBdRyH3KYdPN3
o54DFOgJIYYOJS5bGisJ5bP1sZQpuGsr/zdYhw9tQ0JZvX+3lm5r9MkFNgg+JyjO
4J5+8UrAzxUDLs1suXiogADllYgopLMuuVjY2gNa78OV+0ORfOqx5F9INpDDlUh7
LQVqhf3f+zIvjpf8Ast3wTeUm2PrlaO3QnUFK+PRO/8jFj+7le0o89I6JD7Hkw/9
uUG0cfMBC8z3nEJxVjOOYKxUG/di0th8eHnhY2dnm1YxYqNHaHVHUz02nYeTm1rE
0uFPrb9n7Rx6DVLWD8Xe6oMgGBrBKYozOzzmqYZPAgMBAAGjgYkwgYYwEgYDVR0T
AQH/BAgwBgEB/wIBAzALBgNVHQ8EBAMCAAYwYwYDVR0lBFwwWgYEVR0lAAYIKwYB
BQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDAwYIKwYBBQUHAwQGCCsGAQUFBwMIBggr
BgEFBQcDCQYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDALBgkqhkiG9w0BAQUDggEB
AD9q49T5BEvuerU5O1jRlIijsdTn/Z7VROlc5RO4s2rTVv/whtzSuCB+VF81E2YM
sVebLEQ4zGbvPv6Wp4PwWpLxDjnMZ6cVTLa3ZnQgBc7wZJvgID93j2BkcRtwu6f2
SIdeMlp6ZN1F9iRrgF7E1LvyUIqP0kr3JjjItj+J1sszFLub/DCQsmUAhTfzo4wj
z5rDaC8qaLSWvd3nFqX/7WFxGiyiIR+jDfjBi5zKk+W7GsUN4Y1oc5RT96UgicmB
uAsimukOdKVjXpfiRKNRm81OyXVNhNjLpFd+92kwRXH/VuroUDnF87dBTxChbAcq
EPTsdW6lxTMQ0g2nV0JfKnI=
-----END CERTIFICATE-----

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDqbF/+iB4WbqzN
s5+VeI38O8JIqpQVlSlTBdRyH3KYdPN3o54DFOgJIYYOJS5bGisJ5bP1sZQpuGsr
/zdYhw9tQ0JZvX+3lm5r9MkFNgg+JyjO4J5+8UrAzxUDLs1suXiogADllYgopLMu
uVjY2gNa78OV+0ORfOqx5F9INpDDlUh7LQVqhf3f+zIvjpf8Ast3wTeUm2PrlaO3
QnUFK+PRO/8jFj+7le0o89I6JD7Hkw/9uUG0cfMBC8z3nEJxVjOOYKxUG/di0th8
eHnhY2dnm1YxYqNHaHVHUz02nYeTm1rE0uFPrb9n7Rx6DVLWD8Xe6oMgGBrBKYoz
OzzmqYZPAgMBAAECggEAFvXkdRa587KFZGRqhgZXydPElL94X6DLemFAzKi93abe
zeINsPmUPIi3C52iq7OlcYO5G6B4BZoVjSqjLh2UajxDPGzuHHo0eIhyQ/tl1Uia
m6CuhXp2uunNghFMd5C2+7IF5Ha/7lMrZbErvZmk6HxBaOhCVvaoOiJHHtiRV0aQ
3nYd2tqcAUyMaP05BMIvmfJMY1dpKxEYEe6ISpliUZ+m+GOAz8Wh3gJsmB4qQD5y
mXiBJnt/ZICm34vMNlh8Frk8Y4rNjzW/Nuz0GUKc2uE+NM7ZMKjE9fJ+59cRr2mL
pT8AnfVoaJPn+5vGYO9QqN5b0PsJOJR62UAe10AmIQKBgQD88z7VPCHbpGt3Qf1P
vcW4WSB+dZRvKwnrzQXWdduJHgwXgL6XM835i9OcDSIzH2/XKqLqbM7Q4tMdBoEV
W66B482SJYIO/bs8fTWKvmaclkssOZY3zE+ssCy6OHUUsTjjP/Aa1XYHgYfuXpo8
tQl8kGOarIbNpIEbCgryADt2UQKBgQDtP/HYPlNE+SLx3QgCaUM98nuesa4KJkX1
xTPgW/WWSGKmgYA/8yodWB54/uoaE96r90utgR7kD/EqIZNPI0RKrwdF3Hoyp2cy
NEwbHhfycLdLWMnT3uHXhHe3bHi1oH20Jb4MwBbXXfzT1aqaJg/VkCGpQ/RwV7wJ
87+fmAXqnwKBgQCNTkmkj3IOpFxQg/HBkS8aG9gWLRMdwzpImwEO3Eom4D07B/Xw
u8TuChnNjFy1mHM/DRdzxBMJCB2NkmucBdqHvz3AzelI/J+TXBMEDfd+tEsMSqNL
Snyb6NMjuJRXWeWAteAo7WSBLvBDzl91WGETUAoEhyrLSIHDHCofJNgS8QKBgFQ+
O3sEjn7UVEM7sAdjJzxM6PZtsxXphzgA4S3OmYLWiykCnO6YQqEO1Cs0oR3HZm77
rcSbL8PdoU3LhEo6hJpcUiHNaxqndK5QAaIzal9tBLjdezUfVGQ5pmTcQHSF23zn
VfejEblBp2/009JOp5q2xi0bcyWdEakbAzUBP0CTAoGAZ2PWduB8LWZ5FQw4JTov
rwXTulGRJRGhh4/PuAQ7UlvxzbSmXaetyiASy0z9Svqj1RGSdrlQG5+PtOpBqKZB
7DB2gwSC/bwMZ1Sr4G6F7VWLJyb7BIH2dXmQEGq6taGyCiOju7IogZ3+6TPikpRF
O2vjBR9QTLrMlj0H1y6Dz9c=
-----END PRIVATE KEY-----

注:這裡只對公鑰部分進行處理

3.2.2 執行結果

這裡程式的輸出結果的輸出順序與 1.2 證書組成結構部分順序相同:

在這裡插入圖片描述

  • 版本號:3
  • 序列號:1
  • 簽名演算法:SHA1withRSA
  • 頒發者:C = RU + CN = Test
  • 有效起始日期:Mon Feb 01 00:00:00 CST 2016
  • 有效終止日期:Fri Feb 01 00:00:00 CST 2019
  • 主體名:C=RU + CN=Test
  • 簽名:[[email protected]
  • 公鑰:48,-126,1,34,48,13,6,9,42,-122,72,-122,-9,13,1,1,1,5,0,3,-126,1,15,0,48,-126,1,10,2,-126,1,1,0,-22,108,95,-2,-120,30,22,110,-84,-51,-77,-97,-107,120,-115,-4,59,-62,72,-86,-108,21,-107,41,83,5,-44,114,31,114,-104,116,-13,119,-93,-98,3,20,-24,9,33,-122,14,37,46,91,26,43,9,-27,-77,-11,-79,-108,41,-72,107,43,-1,55,88,-121,15,109,67,66,89,-67,127,-73,-106,110,107,-12,-55,5,54,8,62,39,40,-50,-32,-98,126,-15,74,-64,-49,21,3,46,-51,108,-71,120,-88,-128,0,-27,-107,-120,40,-92,-77,46,-71,88,-40,-38,3,90,-17,-61,-107,-5,67,-111,124,-22,-79,-28,95,72,54,-112,-61,-107,72,123,45,5,106,-123,-3,-33,-5,50,47,-114,-105,-4,2,-53,119,-63,55,-108,-101,99,-21,-107,-93,-73,66,117,5,43,-29,-47,59,-1,35,22,63,-69,-107,-19,40,-13,-46,58,36,62,-57,-109,15,-3,-71,65,-76,113,-13,1,11,-52,-9,-100,66,113,86,51,-114,96,-84,84,27,-9,98,-46,-40,124,120,121,-31,99,103,103,-101,86,49,98,-93,71,104,117,71,83,61,54,-99,-121,-109,-101,90,-60,-46,-31,79,-83,-65,103,-19,28,122,13,82,-42,15,-59,-34,-22,-125,32,24,26,-63,41,-118,51,59,60,-26,-87,-122,79,2,3,1,0,1,

4. 參考文獻


5. 程式碼

Github


6.個人部落格

CSDN