1.OCSP介绍
在PKI体系中,CA机构颁发合法的证书。使用者可以使用CA根证书验证该证书是否被篡改过,但无法从证书文件验证出证书是否被吊销。因此CA机构会通过发布CRL(Certificate Revocation List)来告知所有人,哪些证书已经被吊销。使用者为验证证书的合法性,需要通过验证证书签名来确保证书未被篡改,以及通过CRL查询确保证书未被吊销,此两步都完成后,方可说明证书合法性验证通过。
因CRL巨大且具有时效性,因此设计出OCSP(Online Certificate Status Protocol)机制,可以实时查询证书状态。OCSP比CRL更具有时效性,并且可提供额外的状态信息。本文主要基于RFC6960和RFC5912进行解读。
2.OCSP原理
2.1 OCSP 请求
OCSP请求的ASN.1格式如下:
- tbsRequest:基础请求信息
- version:协议版本,默认为v1,值为0。具有DEFAULT标记,编码时可省略。
- requestorName:请求者名称,可选项
- requestList: 需要检查的证书清单,可包含一个或多个证书信息
- reqCert:需检查的证书信息
- hashAlgorithm:生成issuerNameHash和issuerKeyHash值的HASH算法
- issuerNameHash:证书颁发者的可分辨名称(DN)的HASH值。HASH值应以DER编码值计算(包含完整的TLV)
- issuerKeyHash:颁发者公钥的HASH值
- serialNumber:证书的序列号
- singleRequestExtensions:该证书的请求扩展项,可选项,详见RFC6960 4.4章节。
- reqCert:需检查的证书信息
- requestExtensions:扩展信息。为防止重放攻击,可选择添加1个nonce。
2.optionalSignature: 请求签名,可选项
- signatureAlgorithm: 算法标识符
- signature:签名,对整个tbsRequest进行计算签名
- certs:验证signature的证书,以便OCSP服务器验证signature合法性
当进行OCSP请求时,主要在requestList->reqCert中填充所需认证的证书信息。若一次需检查多个证书,则存在多个reqCert。optionalSignature和requestExtensions等为可选项,通常不使用。
2.2 OCSP响应
OCSP响应的ASN.1格式如下:
- responseStatus:响应状态,为如下值之一
- successful: 值为0,正常响应
- malformedRequest:值为1,非法请求
- internalError:值为2,颁发者内部错误
- tryLater:值为3,稍后重试
- sigRequired:值为5,请求必须进行签名
- unauthorized:值为6,请求未经过授权
- responseBytes:响应内容,只有responseStatus为successful时才存在。
- responseType:对于基础的OCSP响应,此值为id-pkix-ocsp-basic
- response:DER编码的BasicOCSPResponse
- tbsResponseData:响应数据
- version:默认值v1,可省略
- responderID:可填充名称或HASH,若选择HASH,HASH值为OCSP响应者证书的SHA-1值(包含tag和length字段)
- producedAt:OCSP响应程序签署此响应的时间
- responses:校验结果内容。包含N个SingleResponse的数组。OCSP请求中有N个证书,此处就是N个SingleResponse组成的数组,每个SingleResponse的结构如下
- certID:和OCSP请求中的reqCert一致。
- hashAlgorithm:生成issuerNameHash和issuerKeyHash值的HASH算法
- issuerNameHash:证书颁发者的可分辨名称(DN)的HASH值。HASH值应以DER编码值计算
- issuerKeyHash:颁发者公钥的HASH值
- serialNumber:证书的序列号
- certStatus:CHOICE类型,表明当前证书的检查结果,结果为三选一。
- good: NULL,表明OCSP通过
- revoked:表明证书被吊销,会包含吊销时间revocationTime、吊销理由revocationReason(可选)
- unkown:状态未知
- thisUpdate:响应者最近查询状态的时间。此时间不应晚于当前系统时间。
- nextUpdate :建议下次查询时间。此时间不应早于当前系统时间。
- singleExtensions:单个证书附加字段,可选项
- certID:和OCSP请求中的reqCert一致。
- responseExtensions:响应附加字段,可选项。当OCSP请求为防止重放攻击在requestExtensions字段添加noce时,此处应响应相同的noce值。
- signatureAlgorithm:算法标识符
- signature:签名值,基于tbsResponseData(DER编码)内容计算
- certs:验证signature的证书,可选项
- tbsResponseData:响应数据
3.OCSP实践
在了解OCSP原理后,应通过实践验证下解读的原理正确性。本章节以cn.bing.com为目标,进行验证。
3.1 获取X509证书
方法1
使用如下命令:openssl s_client -connect cn.bing.com:443
,将“-----BEGIN CERTIFICATE-----”开始到“-----END CERTIFICATE-----”保存到bing.crt,即为网站证书(注意复制格式,容易出现多余字符串,从而导致出错,建议使用“方法2”)
方法2
用浏览器直接打开cn.bing.com,例如使用chrome
选择最下面的www.bing.com证书,导出文件保存的后缀为crt即可
3.2 查看OCSP URL
方法1
使用如下命令:openssl x509 -noout -ocsp_uri -in bing.crt
可看到OCSP校验地址为http://oneocsp.microsoft.com/ocsp
方法2
在windows中直接双击证书文件bing.crt,在“详细信息”-“授权信息访问”中,可查询到OCSP校验地址
3.3 证书链
如图所示,cn.bing.com的证书链共有三级
将DigiCert Global Root G2和Microsoft Azure RSA TLS Issuing CA 04两个证书分别到处
使用文本工具打开两个证书,将其中的内容复制到1个新文件中,该文件即为证书链文件。需注意Microsoft Azure RSA TLS Issuing CA 04证书放在新文件最开始,DigiCert Global Root G2放在文件后部,合并后的证书链文件如下图:
3.4 OCSP验证
先使用wireshark开启抓包,随后使用如下命令进行OCSP认证请求:
openssl ocsp -issuer "Microsoft Azure RSA TLS Issuing CA 04.crt" -CAfile chain.pem -cert bing.crt -text -url http://oneocsp.microsoft.com/ocsp
,可以看到请求和响应信息,在尾部显示Response Verify Ok,以及bing.crt检查结果是good
抓包文件如下:
ocsp.pcapng
3.5 OCSP请求分析
通过分析wireshark抓包信息,OCSP请求包如下,结合2.1章节OCSP请求格式
optionalSignature未使用,tbsRequest数据解析如下
3.5.1 version
使用默认值,报文中已省略
3.5.2 requestorName
可选项,报文中未使用
3.5.3 requestList
- reqCert字段
-
hashAlgorithm:表明使用SHA-1的HASH算法
-
issuerNameHash:值为16进制的e475019dc323e226741d6c40390795f90596462e。此值由颁发者DN的DER编码通过SHA-1计算出。计算过程如下:
1. 查看bing.crt证书的颁发者
2. 因HASH值需要以DER编码进行计算,故查看DER编码内容
3. 将此段内容单独保存成文件bing-dn.bin(注意格式,以二进制格式保存)
4. 使用openssl命令openssl dgst -sha1 .\bing-dn.bin
计算SHA-1值,结果和请求报文中的值一致。
-
issuerKeyHash:值为16进制的3b70d153e976259d60a8ca660fc69bae6f54166a。此值由颁发者公钥的DER编码(不包含tag和length)通过SHA-1计算出。计算过程如下:
1. bing.crt的颁发者证书为Microsoft Azure RSA TLS Issuing CA 04
2. 查看Microsoft Azure RSA TLS Issuing CA 04.crt的DER编码格式的公钥字段subjectPublicKeyInfo(注意:不包含tag和length)
3.将以上值单独保存到文件Microsoft Azure RSA TLS Issuing CA 04-public.bin(注意格式,以二进制格式保存)
4. 使用openssl命令openssl dgst -sha1 .\Microsoft Azure RSA TLS Issuing CA 04-public.bin
计算SHA-1值,结果和请求报文中的值一致。
-
serialNumber:值为16进制的3300651d5cf9d60cb7fdb542b8000000651d5c,打开bing.crt查看,序列号一致
- singleRequestExtensions:可选项,报文中未使用
3.5.4 requestExtensions
扩展信息报文中包含nonce信息
3.6 OCSP响应分析
OCSP响应抓包内容如下,结合2.3章节分析
3.6.1 responseStatus
报文中值为0x00,代表successful,响应成功
3.6.2 responseBytes
因responseStatus是successful,故此值存在
3.6.2.1 responseBytes
此为基础的OCSP响应,因此值为id-pkix-ocsp-basic
3.6.2.2 response(BasicOCSPResponse)
- tbsResponseData
-
version:默认值,报文中已省略
-
responderID:报文中值为5ec339aeb89e74355bcc6231f9d43644e7eeb07f,计算过程为:
-
producedAt:报文中值为UTF时间
-
responses:因请求就检查1个证书,此处responses数据中只有1个SingleResponse,SingleResponse数据如下
-
certID:值和OCSP请求中的一致。在存在多个SingleResponse时,可用于表明,该数组是对哪个证书的响应。
-
certStatus:ASN.1编码值为80 00,代表good,表明certID标记的证书OCSP验证结果为未吊销,处于正常使用状态
-
thisUpdate:UTC时间,响应者最近查询状态的时间。
-
nextUpdate:UTC时间,建议下次查询时间。
-
singleExtensions:该值解读未仔细查询
-
-
responseExtensions:因OCSP请求中requestExtensions中附加了nonce,因此此处将请求的nonce值返回,以表明响应何请求,避免重放攻击。
-
signatureAlgorithm
指明signature字段使用的签名算法,此处为 -
signature
在signature之前存在一个ASN.1编码为05 00的NULL值,OCSP响应中未发现此定义,也未查询到相关解读,暂留。 -
certs
验证signature的证书,将抓包中的整个Certificate选择,选择复制成Hex Stream,随后以二进制保存到ocsp.crt文件中,该文件即为OCSP响应的验签证书。
文件如下:ocsp.crt
3.7 OCSP响应手动验证
在3.4章节,可以看到openssl已自动验证OCSP响应,结果为通过。此处,进行手动验证OCSP响应。OCSP验证应包含2步:
- 使用证书链验证OCSP响应中certs字段指明的证书是否合法
- 若certs指明的证书通过证书链验证,使用此证书验证OCSP响应中的signature字段签名是否合法
若以上两步均验证通过,可认为OCSP响应合法,则正常读取certStatus状态值,以读取OCSP验证结果。
3.7.1 证书链验证OCSP证书
在3.6章节,我们从OCSP响应的certs字段提取到证书ocsp.crt。使用openssl命令openssl verify -verbose -CAfile chain.pem ocsp.crt
,验证通过:
3.7.2 验证签名
使用ocsp.crt证书验签OCSP响应中的signature,待验签内容为OCSP响应中的tbsResponseData。验签步骤如下:
-
将OCSP响应中的tbsResponseData字段值以二进制格式保存到tbsResponseData.bin文件中
-
将OCSP响应中的signature字段值以二进制保存到ocsp-signature.bin文件中
-
通过signatureAlgorithm字段可知签名算法为sha256WithRSAEncryption
首先从ocsp.crt提取出公钥到ocsp.pem,命令如下:
openssl x509 -in ocsp.crt -pubkey -noout -out ocsp.pem
随后进行验签
openssl dgst -sha256 -verify ocsp.pem -signature ocsp-signature.bin tbsResponseData.bin
可看到验签通过。
4.总结
当要检查某个证书(下称待检查证书A)是否被吊销时,客户端需要发送OCSP请求,OCSP请求中附带“待检查证书A”的序列号等信息,当OCSP服务器收到OCSP请求时,读取OCSP请求中“待检查证书A”的序列号信息,并查询CRL,得到检查结果,随后将检查结果封装到OCSP响应中,使用服务器私钥对OCSP响应进行签名并将签名私钥对应的证书(称为OCSP响应证书B)和签名值附加在OCSP响应中。当客户端收到OCSP响应时,首先使用证书链对OCSP响应中的“OCSP响应证书B”进行验证,验证通过后,再使用“OCSP响应证书B”对OCSP响应中的响应值tbsResponse和签名值signature进行验签,验签通过,则表明OCSP响应合法,此时可读取OCSP响应中“待检查证书A”的校验结果,以确认“待检查证书A”是否被吊销。