1. PKI
PKI(public key infrastructure)的目標是實現不同成員在不見面的情況下進行安全通信,採用的模型是基於證書頒發機構( certification authority或certificate authority, CA)簽發
的證書。PKI體系結構如下圖所示:
- 訂閱人:指那些需要證書來提供安全服務的團體。
- 登記機構:主要是完成一些證書籤發的相關管理工作。可以理解爲代理機構
- 證書頒發機構:既CA,是指證書的頒發機構,它會在確
認申請用戶的身份之後簽發證書。同時CA會在線提供其所簽發證書的最新吊銷信息,這樣信賴方就可以驗證證書是否仍然有效。 - 信賴方:指那些證書使用者,主要指那些需要通過證書在互聯網上進行安全通信的最終用戶。信賴方爲了能夠驗證證書,必須收集信任的所有根CA證書。大多數的操作系統都提供一個根證書庫,幾乎所有的軟件開發者都重用了底層操作系統提供的根證書庫,唯一的例外是Mozilla,爲了保證不同平臺的兼容性,它維護了自己的根證書庫。
2. 證書
證書是一個包含公鑰、訂閱人相關信息以及證書頒發者數字簽名的數字文件。
2.1 證書的分類
證書分類主要包括下面的類型
-
域名驗證型(DV)
- 只驗證網站域名所有權
- 僅能加密通信內容,不能向用戶證明網站的真實身份
- 適合無身份認證需求的網站,如larave_china等
-
組織驗證型(OV)
- 需驗證域名所有權和所屬單位的真實身份。
- 不僅能加密通信內容,還能向用戶證明網站的真實性
- 適應電子商務,企業等網站使用,如亞馬遜商城
-
擴展驗證型(EV)
- 嚴格的身份驗證,最高安全級別
- 提供通信內容加密與網站身份證明,瀏覽器狀態顯示單位名稱。
- 適合金融證券,銀行等網站使用,比如工商銀行
2.2 證書結構
從瀏覽器以及censys(https://censys.io/certificates) 都可以清洗的看到證書的信息:
瀏覽器上部分證書內容如下:
在censys上查詢baidu的證書,部分內容如下(完整內容可查看:https://censys.io/certificates/ed68c58b63218e1d2aa63394b3f23eca26fe5884c9f2235ac2d4ab6edd2f064e/openssl):
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
2c:ee:19:3c:18:82:78:ea:3e:43:75:73
Signature Algorithm: sha256WithRSAEncryption
Issuer:
commonName = PRINTABLESTRING:GlobalSign Organization Validation CA - SHA256 - G2
organizationName = PRINTABLESTRING:GlobalSign nv-sa
countryName = PRINTABLESTRING:BE
Validity
Not Before: May 9 01:22:02 2019 GMT
Not After : Jun 25 05:31:02 2020 GMT
Subject:
commonName = PRINTABLESTRING:baidu.com
organizationName = PRINTABLESTRING:Beijing Baidu Netcom Science Technology Co., Ltd
organizationalUnitName = PRINTABLESTRING:service operation department
localityName = PRINTABLESTRING:beijing
stateOrProvinceName = PRINTABLESTRING:beijing
countryName = PRINTABLESTRING:CN
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:b4:c6:bf:da:53:20:0f:ea:40:f3:b8:52:17:66:
.....
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
Authority Information Access:
CA Issuers - URI:http://secure.globalsign.com/cacert/gsorganizationvalsha2g2r1.crt
OCSP - URI:http://ocsp2.globalsign.com/gsorganizationvalsha2g2
X509v3 Certificate Policies:
Policy: 1.3.6.1.4.1.4146.1.20
CPS: https://www.globalsign.com/repository/
Policy: 2.23.140.1.2.2
X509v3 Basic Constraints:
CA:FALSE
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl.globalsign.com/gs/gsorganizationvalsha2g2.crl
X509v3 Subject Alternative Name:
DNS:baidu.com, DNS:click.hm.baidu.com, DNS:cm.pos.baidu.com,
.............
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Subject Key Identifier:
76:B5:E6:D6:49:F8:F8:36:EA:75:A9:6D:5E:4D:55:5B:37:5C:FD:C7
X509v3 Authority Key Identifier:
keyid:96:DE:61:F1:BD:1C:16:29:53:1C:C0:CC:7D:3B:83:00:40:E6:1A:7C
CT Precertificate SCTs:
Signed Certificate Timestamp:
Version : v1 (0x0)
Log ID : BB:D9:DF:BC:1F:8A:71:B5:93:94:23:97:AA:92:7B:47:
38:57:95:0A:AB:52:E8:1A:90:96:64:36:8E:1E:D1:85
Timestamp : May 9 01:22:04.826 2019 GMT
Extensions: none
Signature : ecdsa-with-SHA256
30:45:02:20:2C:7B:4D:C0:F9:85:47:8A:2D:0A:C0:79:
3B:D6:B4:B5:66:F8:AA:FB:82:58:AD:23:36:FE:16:BC:
A6:83:99:21:02:21:00:C0:2F:CD:9C:99:20:CB:7D:91:
5F:D2:8B:C6:13:10:73:B5:C1:54:03:33:41:9F:A6:6A:
C5:14:93:CF:69:2B:6B
Signature Algorithm: sha256WithRSAEncryption
aa:b9:cd:52:8e:dc:36:5d:47:d4:8b:f3:32:17:06:46:83:60:
...........
證書的字段信息主要包括基本信息,擴展信息,基本信息如下:
- 版本:證書一共有3個版本號,分別用0、 1、 2編碼表示版本1、版本2和版本3。現在大
部分的證書都採用版本3的格式。 - 序列號:每個CA用來唯一標識其所簽發的證書。序列號需要是無序的(無法被預測)而且至少包括20位的熵。
- 簽名算法:指明證書籤名所用的算法,需要放到證書裏面,這樣才能被證書籤名保護。
- 頒發者:證書頒發者的可分辨名稱( distinguished name, DN),這個
字段比較複雜,根據不同的實體會包含許多部分。舉例來說, Verisign根證書的可分辨名
稱是/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority;它
包括了國家、組織和組織單位三個部分。 - 有效期:證書的有效期包括開始日期和結束日期,在這段時間內證書是有效的。
- 使用者:證書使用者的可分辨名稱。
- 公鑰:證書的公鑰
擴展信息:
版本3引入了證書擴展。擴展信息如下:
- 使用者可選名稱(Subject Alternative Name):
基本信息裏的"使用者"字段只能支持與一個主機名進行
綁定,無法同時處理多個身份信息。使用者可選名稱擴展就是爲了替換使用者字段,它
支持通過DNS名稱、 IP地址和URI來將多個身份綁定在一起。 - 名稱約束:名稱約束擴展可以限制CA簽發證書的對象,這樣命名空間就在可控範圍內。這個功能非常有用,例如,它允許一個組織可以擁有一個二級CA,而這個CA只能簽發這個公司所擁有的那些域名下的證書。有了這個限制,CA不能簽發任意網站的證書
- 基礎約束(Basic Constraints):基礎約束擴展用來表明證書是否爲CA證書,同時通過路徑長度( path length)約束字段,來限制二級CA證書路徑的深度
- 密鑰用法( Key Usage):該擴展定義了證書中密鑰可以使用的場景,這些場景已經定義好了,可以通過設置來讓證書支持某個場景。例如CA證書一般都設置了證書籤名者( certificate signer)和CRL簽名者( CRL signer)。
- 擴展密鑰用法(Extended Key Usage):爲了更加靈活地支持和限制公鑰的使用場景,該擴展可以通過該字段支持更多的場景。
- 證書策略(Certificate Policies):該擴展包含了一個或多個策略,每個策略都包括一個OID和可選限定符( qualifier)。限定符一般包括一個URI,從這個URI可以獲得完整的策略說明。
- CRL分發點(CRL Distribution Points):該擴展用來確定證書吊銷列表( certificate revocation list, CRL)的LDAP或者HTTP URI地址。每一張證書都至少需要包括CRL或者OCSP吊銷信息。
- 頒發機構信息訪問( Authority Information Access):該擴展表明如何訪問簽發CA提供的額外信息和服務,例如:OCSP服務。還有一些證書包含了簽發CA的URI地址,有了這個地址,即便服務器返回的證書鏈中缺
少了簽發CA的證書,客戶端也可以通過下載簽發CA重新構建證書鏈。 - 使用者密鑰標識符(Subject Key Identifier):
該擴展可以用來識別包含特別公鑰的證書,一般建議使用公鑰本身來
建立這個標識符(例如通過散列)。所有的CA證書都必須包含這個擴展,並且它的值要與
CA所簽發出來的證書上的授權密鑰標識符的值一樣。 - 授權密鑰標識符(Authority Key Identifier):該擴展是簽發此證書CA的唯一標識符,通常用於在構建證書鏈時找到頒發者
的證書。 - 其他擴展:除了上述的擴展外,還有增量CRL分發點、禁止任意策略、頒
發者可選名稱、策略限制、策略映射、使用者目錄屬性、使用者信息訪問等
2.3 證書的格式
證書可以以各種格式進行存儲,常見的格式如下所示。
-
DER:Binary (DER) certificate
包含原始格式的X.509證書,使用DER ASN.1編碼。 -
PEM:ASCII (PEM) certificate(s)
包含base64編碼過的DER證書,它們以-----BEGIN CERTIFICATE-----開頭,以-----END
CERTIFICATE-----結尾。雖然有些程序可以允許多個證書存在一個文件中,但是一般來說
一個文件只有一張證書。由於該種格式的證書容易查看,所以比較常用。 -
PKCS:PKCS#7 certificate(s)
RFC 2315定義的一種比較複雜的格式,設計的目的是用於簽名和加密數據的傳輸。一般
常見的是.p7b和.p7c擴展名的文件,並且文件裏面可以包括所需的整個證書鏈。 Java的密
鑰管理工具支持這種格式。
Key也可以以各種格式進行存儲,常見的格式如下所示。
-
DER:Binary (DER) key
包含DER ASN.1編碼後的私鑰的原始格式。 OpenSSL使用他自己傳統的方式創建密鑰
( SSLeay)格式。還有另外一種不常使用的格式叫作PKCS#8( RFC 5208定義的)。 OpenSSL
可以使用pkcs8命令進行PKCS#8格式的轉換。 -
ASCII (PEM) key
包括base64編碼後的DER密鑰和一些元數據信息(例如密碼的保存算法)。 -
PKCS#12 (PFX) key and certificate(s)
一種可以用來保存服務器私鑰和整個證書鏈的複雜格式,一般以.p12和.pfx擴展名結尾。
這類格式常見於Microsoft的產品,但是也用於客戶端證書。雖然很久以前PFX表示
PKCS#12之前的版本,現在PFX常被用作PKCS#12的代名詞,不過你已經很難遇到老版
2.4 證書鏈
在大多數情況下,僅僅有最終實體證書是無法進行有效性驗證的,所以在實踐中,服務器需
要提供證書鏈才能一步步地最終驗證到可信根證書,證書鏈的結構如下圖:
證書鏈主要有下面幾個注意事項:
- 保證根證書安全:根證書非常重要,如果根CA的私鑰被泄露,那麼就可以簽發任意域名的虛假證書。另外
如果根CA會被吊銷掉,所有使用這個CA簽發出來的證書的網站都會無法訪問。Baseline Requirements限制所有的根證書密鑰只能由人手動執行命令 - 交叉證書:想將新的CA投入使用,必須基於已經廣泛內置的CA對他們的根密鑰進
行簽名。等老的設備都淘汰掉了,新的CA才能最終獨立使用。 - 二級CA:根CA會將它的操作分散給很多二級CA。例如不同的二級CA用於簽發不同的證書類型。二級CA一般都是在線的,而且使用自動化系統簽發證書。
- 委派:還有一些情況是CA希望給外部其他組織簽發一個二級CA。例如一家大的公司可能希望有自己可控的二級CA。候CA就會從技術上限制這個二級CA只能簽發某些域名;
理論上服務器一次只能提供一條證書鏈,而實際上可能存在多條可信路徑,例如交叉證書。
多路徑以及證書配置的問題是很多安全問題的根源。歷史上有很多驗證庫在驗證簽發CA屬於哪個根CA這類簡單問題上都出現過問題。
2.5 證書吊銷
當出現私鑰泄露或者不再需要使用的時候,我們就需要吊銷證書,方式主要有以下兩種:
- 證書吊銷列表( certificate revocation list, CRL):是一組未過期、但是卻已經被吊銷的證書序列號列表, CA維護了一個或多個這樣的列表。每一張證書都需要在CRL分發點( CRL
distribution point)擴展中包含對應的CRL地址。CRL最大的問題在於它越來越大,實時查
詢起來會非常慢。 - 在線證書狀態協議( online certificate status protocol, OCSP):允許信賴方獲得一張證書的
吊銷信息。 OCSP程序的地址編碼在頒發機構
信息訪問( authority information access, AIA)證書擴展中。 OCSP支持實時查詢並且解決了CRL最大的缺點,但是並沒有解決所有的吊銷問題:因爲OCSP的使用帶來了性能、隱私方面的問題和新的漏洞。其中一部分問題可以通過OCSP stapling技術來解決,它允許服務器在TLS握手的過程中直接嵌入OCSP響應
3. 存在問題與解決方案
人無完人,PKI體系雖然很強大,但也存在一些問題,問題如下:
- 任何CA都可以在未經域名所有者授權的情況下籤發該域名的證書
- 信賴方維護了包含一定數量CA證書的根證書庫,這樣CA要麼是完全可信,要麼完全不可信,沒有中間情況。
- DV證書是通過不安全的WHOIS協議獲取域名信息,然後基於域名所有者信息來簽發證書
的。此外,驗證過程經常是用郵件溝通,本身也是不安全的 - 吊銷可能不生效
- 很多庫和應用完全繞過了驗證過程,例如:瀏覽器雖然會檢測證書,但是當遇到無效證書時,它們卻又允許用戶忽略警告信息
下述方案可以解決上面的部分問題:
- 公鑰釘扎:公鑰釘扎解決了當前PKI生態系統裏面最大的弱點,也就是任何CA都可以在未經域名擁有者同意的情況下給任意域名簽發證書。有了釘扎之後,網站的擁有者可以選擇(釘)一個或者多個他們信任的CA,創造他們自己單獨的、比全球生態系統小很多的可信生態
系統。 - DNSSEC:DNSSEC是在DNS的基礎上擴展了完整性檢查的一組新協議。有了DNSSEC,域名可以與一組密鑰關聯起來,這一組密鑰用於給對應DNS區進行簽名。 DANE是DNSSEC和TLS驗
證之間的橋樑。雖然DANE也可以用來做釘子,但是它最令人感興趣的能力是完全繞過公
共CA,如果你信任DNS,就可以用它做TLS驗證。 - 證書透明度:證書透明度( certificate transparency, CT) 是一套審計和監控公開證書的框架。 CA將他們簽發的每一張證書都提交到公開證書日誌裏面,然後獲得一個此次已提交的加密證明。任何人都可以監控CA簽發的每一張新證書。例如域名擁有者可以監控每一張簽發了他們
域名的證書。這個想法如果實現的話,那麼虛假證書就可以快速地被發現。上述例子中百度的證書裏就已經包含了CT的信息