PKIX

**X.509** 是密碼學裡公鑰憑證的格式標準。X.509 憑證已應用在包括 TLS/SSL 在內的眾多網路協定里，同時它也用在很多非線上應用場景里，比如電子簽章服務。X.509 憑證里含有公鑰、身分資訊（比如網路主機名，組織的名稱或個體名稱等）和簽章資訊（可以是憑證簽發機構 CA 的簽章，也可以是自簽章）。

X.509 還附帶了憑證吊銷列表和用於從最終對憑證進行簽章的憑證簽發機構直到最終可信點為止的憑證合法性驗證演算法。X.509 是 ITU-T 標準化部門基於他們之前的 ASN.1 定義的一套憑證標準。

## 歷史及使用情況

X.509 最早與 X.500 一起發布於 1988 年 7 月 3 日。它假設有一套嚴格的層次化的憑證頒發機構（CA）。X.500 系統僅由主權國家實施，以實現國家身分資訊共享條約的實施目的；而 IETF 的公鑰基礎設施（X.509）簡稱 PKIX 工作群組將該標準制定成適用於更靈活的網際網路組織。而且事實上 X.509 認證指的是 RFC5280 里定義的 X.509 v3，包括對 IETF 的 PKIX 憑證和憑證吊銷列表，通常也稱為公鑰基礎設施（PKI）。

## 憑證

在 X.509 裡，組織機構通過發起憑證簽章請求（CSR）來得到一份簽章的憑證。首先需要生成一對金鑰對，然後用其中的私鑰對 CSR 進行數位簽署（簽名），並安全地儲存私鑰。CSR 進而包含有請求發起者的身分資訊、用來對此請求進行驗真的的公鑰以及所請求憑證專有名稱。CSR 里還可能帶有 CA 要求的其它有關身分證明的資訊。然後 CA 對這個 CSR 進行簽名。
組織機構可以把受信的根憑證分發給所有的成員，這樣就可以使用公司的 PKI 系統了。瀏覽器（如 Firefox）或作業系統預裝有可信任的根憑證列表，所以主流 CA 發布的 TLS 憑證都直接可以正常使用。瀏覽器的開發者直接影響著它的使用者對 CA 的信任。X.509 也定義了 CRL 實現標準。另一種檢查合法性的方式是 OCSP。

### 憑證組成結構

憑證組成結構標準用 ASN.1（一種標準的語言）來進行描述.
X.509 v3 數位憑證結構如下：

* 憑證
  * 版本號
  * 序列號
  * 簽章演算法
  * 頒發者
  * 憑證有效期
    * 此日期前無效
    * 此日期後無效
  * 主題
  * 主題公鑰資訊
    * 公鑰演算法
    * 主題公鑰
  * 頒發者唯一身分資訊（可選項）
  * 主題唯一身分資訊（可選項）
  * 擴充資訊（可選項）
    * ...
* 憑證簽章演算法
* 數位簽章

所有擴充都有一個 ID，由 object identifier 來表達。它是一個集合，並且有一個標記用與指示這個擴充是不是決定性的。憑證使用時，如果發現一份憑證帶有決定性標記的擴充，而這個系統並不清楚該擴充的用途，那麼要拒絕使用它。但對於非決定性的擴充，不認識可以予以忽略。RFC 1422 給出了 v1 的憑證結構
ITU-T 在 v2 里增加了頒發者和主題唯一識別碼，從而可以在一段時間後可以重用。重用的一個例子是當一個 CA 破產了，它的名稱也在公共列表里清除掉了，一段時間之後另一個 CA 可以用相同的名稱來註冊，即使它與之前的並沒有任何瓜葛。不過 IETF 並不建議重用同名註冊。另外 v2 在 Internet 也沒有多大範圍的使用。
v3 引入了擴充。CA 使用擴充來發布一份特定使用目的的憑證（比如說僅用於代碼簽章）
所有的版本中，同一個 CA 頒發的憑證序列號都必須是唯一的。

### 擴充指定了憑證的用途

RFC 5280（及後續版本）定義了一些擴充用來指定憑證的用途。 它們的多數都來源於 joint-iso-ccitt(2) ds(5) id-ce(29) OID。在 4.2.1 里定義的幾個常用擴充定義如下：

* Basic Constraints， { id-ce 19 } 用於指定一份憑證是不是一個 CA 憑證。
* Key Usage, { id-ce 15 }, 指定了這份憑證包含的公鑰可以執行的密碼操作。作為一個例子，它可以指定只能用於簽章，而不能用來進行加密操作。
* Extended Key Usage, { id-ce 37 }, 典型用法是用於葉子憑證中的公鑰的使用目的。它包括一系列的 OID，每一個都指定一種用途。比如{ id-pkix 3 1 } 表示用於伺服器端的 TLS/SSL 連接，而{ id-pkix 3 4 }用於 email 的安全操作。

通常情況下，一份憑證有多個限制用途的擴充時，所有限制條件都應該滿足才可以使用。RFC 5280 里有對一個同時含有 keyUsage 和 extendedKeyUsage 的憑證的例子，這樣的憑證只能用在兩個擴充中都指定了的用途。比如網路安全服務決定憑證用途時會同時對這兩個擴充進行判斷

### 憑證副檔名

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

* .pem – 隱私增強型電子郵件格式，通常是 Base64 格式的。
* .cer, .crt, .der – 通常是 DER 二進位格式的。
* .p7b, .p7c – PKCS#7 SignedData structure without data, just certificate(s) or CRL(s)
* .p12 – PKCS#12 格式，包含憑證的同時可能還包含私鑰
* .pfx – PFX，PKCS#12 之前的格式（通常用 PKCS#12 格式，比如由網際網路資訊服務產生的 PFX 檔案）

PKCS#7 是簽章或加密資料的格式標準，官方稱之為容器。由於憑證是可驗真的簽章資料，所以可以用 SignedData 結構表述。 .P7C 檔案是退化的 SignedData 結構，沒有包括簽章的資料。

PKCS#12 由 PFX 進化而來的用於交換公共的和私有的物件的標準格式。

## 憑證鏈和交叉認證

**憑證鏈**（也就是 RFC 5280 里的憑證路徑) 是從終端使用者憑證後跟著一系列的 CA 憑證，而通常最後一個是自簽章憑證，並且有如下關係：

1. 在憑證鏈上除最後一個憑證外，憑證頒發者等於其後一個憑證的主題。
2. 除了最後一個憑證，每個憑證都是由其後的一個憑證簽章的。
3. 最後的憑證是信任主題，由於是通過可信過程得到的，你可以信任它。

憑證鏈用於檢查目標憑證（憑證鏈里的第一個憑證）里的公鑰及其它資料是否屬於其主題。檢查是這麼做的，用憑證鏈中的下一個憑證的公鑰來驗證它的簽章，一直檢查到憑證鏈的尾端，如果所有驗證都成功通過，那個這個憑證就是可信的。

下面是對 RFC 5280 里定義的憑證路徑合法性演算法的一個簡要介紹，包括對憑證的有效期、CRL 等其它額外的檢查。

對於具體的憑證來說，有一點需要注意的是它可能存在於很不一樣的兩條或多條憑證鏈中，並且都是合法的。這是因為 CA 憑證可以來自多個頒發者，或者來自相同頒發者但用不同的私鑰簽發，這樣在 CA 憑證上會出現分叉，從而可以出現多條憑證鏈。這也是 PKI 之間交叉認證和其它應用的關鍵所在。

看下面的例子：

在這兩個圖里：

* 方塊代表憑證，加黑的是憑證的主題名字。
* A → B 表示 "A 是由 B 簽發的" （更確切地說，A 是由 B 中所載公鑰對應的私鑰簽署的）
* 相同顏色（透明色和白色除外）的憑證具有相同的公鑰

### 例 1: 兩個 PKI 之間的根憑證交叉認證

為了讓 PKI2 的使用者憑證也得到 PKI1 的信任，CA1 生成一包含 CA2 公鑰的憑證 cert2.1
這時候 cert2 和 cert2.1 具體相同的主題及公鑰，cert2.2 (User 2) 就有了兩條合法的憑證鏈："cert2.2 → cert2" and "cert2.2 → cert2.1 → cert1"。

CA2 也可以生成類似的包含有 CA1 公鑰的憑證 cert1.1，以便 PKI1 的使用者 (比如 User 1) 的憑證能在 PKI2 得到認證。

### 例 2: CA 憑證更新

Understanding Certification Path Construction (PDF). PKI Forum. September 2002 [2018-04-28]. （原始內容 (PDF) 存檔於 2019-02-04）. 為了憑證頒發者從舊的私鑰順利地轉移到新的私鑰，他可以頒發兩個憑證，其中一個是新的私鑰對舊的公鑰進行簽章，另一個是舊的私鑰對新的公鑰的簽章，這兩個都是機構自己給自己頒發的憑證，但都不是自簽章憑證。註：另外還存在新舊兩個自簽章憑證。 

假設 cert1 和 cert3 具有相同的公鑰，對於 cert5 來說有兩條合法的憑證鏈，cert5 → cert1 和 cert5 → cert3 → cert2, cert6 的情況也類似。這樣就允許老的使用者憑證可以在新舊兩個根憑證之間平滑轉移。

## X.509 憑證樣例

下面是 GlobalSign 頒發的用於 wikipedia.org 以及一些其它 Wikipedia 網站 X.509 憑證。憑證頒發者填在頒發者 (Issuer) 欄位，主題內容里是組織機構 Wikipedia 的描述，主題備用名稱是那些採用該憑證的伺服器的主機名。主題公鑰里的資訊表明採用的是橢圓曲線公共金鑰，位於最後的簽章演算法表示它是由 GlobalSign 用其私鑰並採用帶 RSA 加密的 SHA-256 演算法進行簽章的。

### 最終實體憑證（或者叫葉子憑證）

```
  認證:
          版本: 3 (0x2)
        序號: 10:e6:fc:62:b7:41:8a:d5:00:5e:45:b6
      簽章演算法: sha256WithRSAEncryption
        發行者: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2
      有效期開始時間: Nov 21 08:00:00 2016 GMT
      有效期結束時間: Nov 22 07:59:59 2017 GMT
         主體: C=US, ST=California, L=San Francisco, O=Wikimedia Foundation, Inc., CN=*.wikipedia.org
  主體公鑰信息(subject public key info):
            公鑰算法: id-ecPublicKey
         256位的公鑰:
                    04:c9:22:69:31:8a:d6:6c:ea:da:c3:7f:2c:ac:a5:
                    af:c0:02:ea:81:cb:65:b9:fd:0c:6d:46:5b:c9:1e:
                    ed:b2:ac:2a:1b:4a:ec:80:7b:e7:1a:51:e0:df:f7:
                    c7:4a:20:7b:91:4b:20:07:21:ce:cf:68:65:8c:c6:
                    9d:3b:ef:d5:c1
          ASN1 OID: prime256v1
          NIST CURVE: P-256
       額外資訊(extension):
          密鑰使用: 
               敏感訊息(critical):是
               公鑰用途:數位簽章，密鑰協商Key Agreement
       授權相關訊息: 
               敏感訊息(critical):否
                頒發者URI:http://secure.globalsign.com/cacert/gsorganizationvalsha2g2r1.crt
  線上憑證狀態協定(OCSP)URI:http://ocsp2.globalsign.com/gsorganizationvalsha2g2

         證書原則(Certificate Policies): 
               敏感訊息(critical):否
          policy ID#1: 1.3.6.1.4.1.4146.1.20
           CPS URI: https://www.globalsign.com/repository/
          policy ID#2: 2.23.140.1.2.2

          基本限制: 
                CA:FALSE
       憑證撤銷中心(X509v3 CRL Distribution Points): 
               敏感訊息(critical):否
               URI:http://crl.globalsign.com/gs/gsorganizationvalsha2g2.crl

       主體備用名稱: 
               敏感訊息(critical):否
               DNS:*.wikipedia.org, DNS:*.m.mediawiki.org, DNS:*.m.wikibooks.org, DNS:*.m.wikidata.org, DNS:*.m.wikimedia.org, DNS:*.m.wikimediafoundation.org, DNS:*.m.wikinews.org, DNS:*.m.wikipedia.org, DNS:*.m.wikiquote.org, DNS:*.m.wikisource.org, DNS:*.m.wikiversity.org, DNS:*.m.wikivoyage.org, DNS:*.m.wiktionary.org, DNS:*.mediawiki.org, DNS:*.planet.wikimedia.org, DNS:*.wikibooks.org, DNS:*.wikidata.org, DNS:*.wikimedia.org, DNS:*.wikimediafoundation.org, DNS:*.wikinews.org, DNS:*.wikiquote.org, DNS:*.wikisource.org, DNS:*.wikiversity.org, DNS:*.wikivoyage.org, DNS:*.wiktionary.org, DNS:*.wmfusercontent.org, DNS:*.zero.wikipedia.org, DNS:mediawiki.org, DNS:w.wiki, DNS:wikibooks.org, DNS:wikidata.org, DNS:wikimedia.org, DNS:wikimediafoundation.org, DNS:wikinews.org, DNS:wikiquote.org, DNS:wikisource.org, DNS:wikiversity.org, DNS:wikivoyage.org, DNS:wiktionary.org, DNS:wmfusercontent.org, DNS:wikipedia.org
    
    (在額外訊息中的)密鑰使用目的:
               敏感訊息(critical):否
              目的1:TLS Web伺服器鑑定
              目的2:TLS Web客户端鑑定
    主體密鑰識別代碼(Subject Key Identifier): 
               敏感訊息(critical):否
               密鑰id: 28:2A:26:2A:57:8B:3B:CE:B4:D6:AB:54:EF:D7:38:21:2C:49:5C:36
    授權密鑰識別代碼(X509v3 Authority Key Identifier): 
               敏感訊息(critical):否
               密鑰id:96:DE:61:F1:BD:1C:16:29:53:1C:C0:CC:7D:3B:83:00:40:E6:1A:7C

        簽章算法: sha256WithRSAEncryption
             數位簽章: 8b:c3:ed:d1:9d:39:6f:af:40:72:bd:1e:18:5e:30:54:23:35:
         ...
```

 
要驗證這個憑證，我們需要一個跟該憑證頒發者及授權金鑰識別碼

都匹配的中間憑證

組態正確的伺服器可以在 TLS 連接建立的握手階段同時提供其中間憑證。但是也有可能需要根據憑證里頒發者的 URL 去取得中間憑證。

### 中間憑證

下面是憑證頒發機構的憑證範例。該憑證是由下例根憑證簽章的用於頒發上例最終實體憑證的憑證。當然它的主題識別碼跟上例憑證的授權金鑰識別碼是相匹配的。

```
 证书:
          版本: 3 (0x2)
        序列号: 04:00:00:00:00:01:44:4e:f0:42:47
      签名算法: sha256WithRSAEncryption
        颁发者: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
      此前无效: Feb 20 10:00:00 2014 GMT
      此后无效: Feb 20 10:00:00 2024 GMT
         主题: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2
  主题公钥信息:
            公钥算法: rsaEncryption
        2048位的公钥:
                    00:c7:0e:6c:3f:23:93:7f:cc:70:a5:9d:20:c3:0e:
                    ...
               指数: 65537 (0x10001)
  X509 v3扩展:
   X509v3 密钥使用: 
               关键:是
               用于:证书签名, CRL签名
          基本约束:
               关键:是
        证书颁发机构:是
        路径长度限制:0
    主题密钥标识符: 
               关键:否
                密钥: 96:DE:61:F1:BD:1C:16:29:53:1C:C0:CC:7D:3B:83:00:40:E6:1A:7C
                96:DE:61:F1:BD:1C:16:29:53:1C:C0:CC:7D:3B:83:00:40:E6:1A:7C
        证书策略:
               关键:否
               策略1: 任何策略标识符
            CPS URI: https://www.globalsign.com/repository/

     CRL 分发点:
               关键:否
                URI:http://crl.globalsign.net/root.crl

       授权相关信息: 
               关键:否
  在线证书状态协议(OCSP)URI:http://ocsp.globalsign.com/rootr1

     授权密钥标识符:
               关键:否
                    密钥:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B

        签名算法: sha256WithRSAEncryption
             数字签名:46:2a:ee:5e:bd:ae:01:60:37:31:11:86:71:74:b6:46:49:c8:
         ...
```

### 根憑證

下面是憑證頒發機構的自簽章根憑證。它的頒發者和主題是相同的，可以用自身的公鑰進行合法認證。憑證認證過程也將在此終止。如果應用已經在它的可信公鑰存貯里已經含有該公鑰憑證，那麼 TLS 連接時的那個最終實體憑證是可信的，否則就是不可信的。

```
 证书:
          版本: 3 (0x2)
        序列号: 04:00:00:00:00:01:15:4b:5a:c3:94
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
        Validity
            Not Before: Sep  1 12:00:00 1998 GMT
            Not After : Jan 28 12:00:00 2028 GMT
        Subject: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:da:0e:e6:99:8d:ce:a3:e3:4f:8a:7e:fb:f1:8b:
                    ...
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Subject Key Identifier: 
                60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B
    Signature Algorithm: sha1WithRSAEncryption
         d6:73:e7:7c:4f:76:d0:8d:bf:ec:ba:a2:be:34:c5:28:32:b5:
         ...
```

## 安全性

布魯斯・施奈爾、彼得・古特曼及其他安全專家已經發布了很多 PKI 的安全問題。

### 架構的弱點

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

### 憑證頒發機構問題

* 即使主題實體購買了擴充驗證的憑證，他的付出也並不能得到相應的回報，因為這並不能阻止通過更便宜的憑證頒發機構購買相同主題內容的憑證的行為
* 憑證頒發機構不能給使用者提供主題甚至組織團體上的擔保，無法阻止同名憑證
* 憑證有效期應該限制在金鑰強度可保護的範圍內。但這個欄位卻被憑證頒發機構誤用為收費依據從而讓使用者處於金鑰可能被破解的情況下
* "如果使用者通過一種未定義的憑證請求協定去獲得子一個位址不明的，不存在於任何目錄下的憑證，那麼你也沒辦法吊銷這個憑證。"

## 參考文獻

## 外部連結

* ITU-T Recommendation X.509 : Information technology - Open Systems Interconnection - The Directory: Public-key and attribute certificate frameworks （頁面存檔備份，存於網際網路檔案館）