我們在進行網頁存取的時候會跟各種各樣的證書打交道,比如在存取https網頁的時候,需要檢測https網站的證書有效性。
OCSP就是一種校驗協定,用於獲取X.509數位憑證的復原狀態。它是為了替換CRL而出現的。
本文將會詳細介紹OCSP的實現和優點。
我們知道在PKI架構中,CA證書是非常重要的元件,使用者端通過CA證書來驗證服務的可靠性。對於CA證書本身來說在建立的時候是可以指定過期時間的。這樣證書在過期之後就不可以使用,需要申請新的證書。
但是隻給證書指定過期時間是不夠的,比如我們因為業務的需求,需要復原證書怎麼辦呢?
PKI中提供了一個叫做CRL(certificate revocation list)的機制,用來維持被廢除的證書列表。
這個CRL是由CA來頒發的,一般是在證書過期之前生成的。因為如果證書已經過期了,那麼這個CRL是無意義的。
對於CRL本身來說,它是一個證書列表,裡面證書的格式通常也使用的是X.509。
CRL一般是由釋出證書的CA來維護和釋出的,釋出CRL的元件叫做CRL issuer,通常來說CRL issuer和CA是同一個服務,但是你也可以根據需要將CRL issuer和CA進行拆分。
CRL是由CA定時來發布的,當然你也可以按照需要在需要復原某個CA證書的時候重新發布CRL。所有的CRL都有過期時間,在這個過期時間之內,使用者端可以根據CRL中的簽名,去CA驗證CRL的有效性,從而防止CRL的偽造。
那麼CRL有什麼缺點呢?
首先CRL維持的是一個復原的證書列表,為了保證系統的有效性,使用者端在每次校驗CA證書有效性的時候,都需要從CA伺服器中獲取這個CRL。然後通過CRL來校驗對應的CA證書狀態。
如果每次都去拿這個CRL,就有可能會有下面幾個問題。
第一個問題是,如果CRL不可用,那麼使用者端就拿不到這個CRL,也就無法校驗CA證書的狀態,從而造成服務不可用。
另外一個問題是,如果要復原的證書比較多的話,這個CRL可能會比較大,從而造成網路資源的浪費。
最後一個問題是PKI證書體系本身的目的是建立一個可以自我校驗的,不依賴於線上服務的安全體系,如果每次都要線上獲取CRL的話,就是去了PKI的這一優勢。
雖然CRL維持的是一個復原證書列表,但是這個列表中證書的狀態還是有所不同的。
CRL中證書的狀態有兩種,第一種就是證書已經被複原了,比如證書的頒發機構CA發現之前的頒佈的證書是錯誤的,或者因為其他的原因如私鑰洩露導致原來的證書不夠安全,需要將證書撤回。或者證書機構因為未遵守某些策略導致證書被吊銷等,都需要將之前的證書設定為復原狀態。
還有一種狀態是一個臨時復原的狀態,這裡叫做Hold狀態,它表示證書暫時是無效的,比如在使用者沒有確定私鑰是否丟失的情況下。當用戶最終找回了私鑰,則這個證書還是可以被恢復的。
既然CRL有這麼多缺點,所以一個用來替代CRL的OCSP協定出現了。
我們先來看一下OCSP的工作流程。
假如A和B要進行使用PKI進行通訊。為了保證通訊的安全性,A將自己的公鑰發給B,並告訴B,這是我的公鑰,你可以用這個公鑰來校驗我傳送給你的訊息。
B在收到A的公鑰之後,並不能確定A的公鑰就是正確的,沒有被篡改的。於是從A的公鑰中提取出serial number,並將其封裝到一個'OCSP request'中發給CA伺服器。
CA伺服器中的OCSP responder讀取到了'OCSP request'請求,並從中提取出A的公鑰的serial number。OCSP responder從CA伺服器的資料庫中查詢這個serial number是否在這個資料庫被複原的列表中。
如果發現不在,那麼意味著A的公鑰仍然是有效的,OCSP responder將會傳送一個簽名後的OCSP response給B。
B通過使用CA伺服器的公鑰驗證OCSP response的有效性,從而確認A的公鑰仍然有效 。
最後B使用A的公鑰和A進行通訊。
從上面的OCSP的工作流程我們可以大概總結出下面幾個OCSP相對於CRL的優點。
首先OCSP響應的資料量要比CRL要小,所以對網路的要求和壓力更少。
另外因為OCSP響應要解析的資料更少,所以OCSP使用者端的實現要比CRL更加簡單。
雖然因為CRL的各種缺點,在web環境中已經不再被使用,而是被更加高效的OCSP替換,但是CRL仍然被執行在CA的其他環境中。
OCSP協定是在RFC 6960中定義的。
OCSP協定可以分為請求協定和響應協定兩部分,接下來分別來進行介紹。
一個OCSP請求需要包含協定版本號,請求服務,要校驗的證書identifier和可選的擴充套件部分。
OCSP responder在接收到OCSP的請求之後,會去校驗OCSP訊息的有效性,如果訊息有問題則會返回異常,否則的話會根據請求的服務進行處理。
OCSP請求如果用ASN.1(Abstract Syntax Notation One)抽象語法標記這可以如下表示:
OCSPRequest ::= SEQUENCE {
tbsRequest TBSRequest,
optionalSignature [0] EXPLICIT Signature OPTIONAL }
TBSRequest ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT v1,
requestorName [1] EXPLICIT GeneralName OPTIONAL,
requestList SEQUENCE OF Request,
requestExtensions [2] EXPLICIT Extensions OPTIONAL }
Signature ::= SEQUENCE {
signatureAlgorithm AlgorithmIdentifier,
signature BIT STRING,
certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL}
Version ::= INTEGER { v1(0) }
Request ::= SEQUENCE {
reqCert CertID,
singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL }
CertID ::= SEQUENCE {
hashAlgorithm AlgorithmIdentifier,
issuerNameHash OCTET STRING, -- Hash of issuer's DN
issuerKeyHash OCTET STRING, -- Hash of issuer's public key
serialNumber CertificateSerialNumber }
ASN.1是一個介面描述語言,通過ASN.1,我們可以很清晰的描述資料的格式資訊。
一個OCSPRequest是由可選擇簽名的OCSP請求tbsRequest和對應的簽名optionalSignature組成的。
其中TBSRequest中包含了版本號,OCSP requestor的名字,證書的狀態列表requestList,可選的擴充套件資料這幾項組成的。
對於OCSP的響應來說,根據傳輸協定的不同它的結構也是不同的。但是所有的響應都應該包含responseStatus欄位表示請求的處理狀態。
OCSP響應用ASN.1格式來表示如下所示:
OCSPResponse ::= SEQUENCE {
responseStatus OCSPResponseStatus,
responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
OCSPResponseStatus ::= ENUMERATED {
successful (0), -- Response has valid confirmations
malformedRequest (1), -- Illegal confirmation request
internalError (2), -- Internal error in issuer
tryLater (3), -- Try again later
-- (4) is not used
sigRequired (5), -- Must sign the request
unauthorized (6) -- Request unauthorized
}
ResponseBytes ::= SEQUENCE {
responseType OBJECT IDENTIFIER,
response OCTET STRING }
responseStatus是響應的狀態,responseBytes是可選的響應結果。
這裡的response是一個BasicOCSPResponse物件的DER編碼:
BasicOCSPResponse ::= SEQUENCE {
tbsResponseData ResponseData,
signatureAlgorithm AlgorithmIdentifier,
signature BIT STRING,
certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
可以看到OCSP需要客戶在需要檢視證書是否被吊銷的時候,需要向OCSP responser請求,以確認證書的有效性。
但是這種方式實際上洩露了使用者的隱私資訊,因為OCSP responser知道了使用者端需要校驗的證書,就知道使用者端正在存取的網站。
於是引入了OCSP stapling來解決這個問題。
那麼什麼是OCSP stapling呢?
OCSP stapling是直接將OCSP證書放到使用者端要存取的web伺服器上,因為OCSP證書是新增了時間戳和數位簽章的,所以可以保證其正確性。
這些OCSP證書會在使用者端和web端建立SSL 握手的時候就包含在OCSP響應中。
這樣使用者端不需要單獨和CA建立額外的連線,從而提高了效能。
OCSP stapling需要在伺服器端主動開啟。
如果你用的是apache伺服器,首先需要版本大於2.3.3。
然後需要在.conf檔案中的<VirtualHost></VirtualHost>
block外部新增:
SSLStaplingCahe shmcb: /tmp/stapling_cache(128000)
然後在<VirtualHost></VirtualHost>
block的內部新增:
SSLUseStapling On
如果你用的是nginx,首先需要版本大於1.3.7。
然後在nginx的組態檔server {}
block中新增:
ssl_stapling on;
ssl_stapling_verify on;
如果你想驗證一個網站是否開啟了OCSP stapling,可以到https://entrust.ssllabs.com/網站中進行查詢:
在這個網站中,你可以輸入任何要查詢的網站地址,然後可以得到下面的資訊:
可以看到這個網站是開啟了OCSP stapling的。
OCSP和OCSP stapling是非常有用的證書復原校驗協定,已經被廣泛的使用。大家可以檢查一下自己的網站有沒有用到哦。
更多內容請參考 http://www.flydean.com/43-pki-ocsp/
最通俗的解讀,最深刻的乾貨,最簡潔的教學,眾多你不知道的小技巧等你來發現!
歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!