模块 OpenSSL::OCSP
OpenSSL::OCSP
实现了在线证书状态协议的请求和响应。
创建和发送 OCSP
请求需要一个包含 authorityInfoAccess 扩展中 OCSP
URL 的主题证书,以及主题证书的颁发者证书。首先,加载颁发者和主题证书
subject = OpenSSL::X509::Certificate.new subject_pem issuer = OpenSSL::X509::Certificate.new issuer_pem
要创建请求,我们需要为主题证书创建一个证书 ID,以便 CA 知道我们正在查询哪个证书
digest = OpenSSL::Digest.new('SHA1') certificate_id = OpenSSL::OCSP::CertificateId.new subject, issuer, digest
然后创建一个请求,并将证书 ID 添加到其中
request = OpenSSL::OCSP::Request.new request.add_certid certificate_id
在请求中添加一个随机数可以防止重放攻击,但并非所有 CA 都会处理随机数。
request.add_nonce
要将请求提交到 CA 进行验证,我们需要从主题证书中提取 OCSP
URI
ocsp_uris = subject.ocsp_uris require 'uri' ocsp_uri = URI ocsp_uris[0]
要提交请求,我们将请求 POST 到 OCSP
URI
(根据 RFC 2560)。请注意,在此示例中,我们仅处理 HTTP 请求,而不处理任何重定向,因此这不足以用于严肃的用途。
require 'net/http' http_response = Net::HTTP.start ocsp_uri.hostname, ocsp_uri.port do |http| http.post ocsp_uri.path, request.to_der, 'content-type' => 'application/ocsp-request' end response = OpenSSL::OCSP::Response.new http_response.body response_basic = response.basic
首先,我们检查响应是否具有有效的签名。如果没有有效的签名,我们无法信任它。如果在此处收到失败,则可能是您缺少系统证书存储区,或者可能缺少中间证书。
store = OpenSSL::X509::Store.new store.set_default_paths unless response_basic.verify [], store then raise 'response is not signed by a trusted certificate' end
响应包含状态信息(成功/失败)。我们可以将状态显示为字符串
puts response.status_string #=> successful
接下来,我们需要知道响应的详细信息,以确定响应是否与我们的请求匹配。首先,我们检查随机数。同样,并非所有 CA 都支持随机数。有关返回值含义,请参见 Request#check_nonce
。
p request.check_nonce basic_response #=> value from -1 to 3
然后从基本响应中提取证书的状态信息。
single_response = basic_response.find_response(certificate_id) unless single_response raise 'basic_response does not have the status for the certificate' end
然后检查有效性。将来发布的任何状态都必须被拒绝。
unless single_response.check_validity raise 'this_update is in the future or next_update time has passed' end case single_response.cert_status when OpenSSL::OCSP::V_CERTSTATUS_GOOD puts 'certificate is still valid' when OpenSSL::OCSP::V_CERTSTATUS_REVOKED puts "certificate has been revoked at #{single_response.revocation_time}" when OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN puts 'responder doesn't know about the certificate' end
常量
- NOCASIGN
-
(此标志不被
OpenSSL
1.0.1g 使用) - NOCERTS
-
不要在响应中包含证书
- NOCHAIN
-
不要验证响应中的证书链
- NOCHECKS
-
不要进行额外的签名证书检查
- NODELEGATED
-
(此标志不被
OpenSSL
1.0.1g 使用) - NOEXPLICIT
-
不检查信任
- NOINTERN
-
不要在响应中搜索包含的证书以查找签名者
- NOSIGS
-
不要检查响应上的签名
- NOTIME
-
不要在响应中包含 producedAt 时间
- NOVERIFY
-
根本不验证响应
- RESPID_KEY
-
通过签名证书密钥 ID 来标识响应
- RESPONSE_STATUS_INTERNALERROR
-
颁发者内部错误
- RESPONSE_STATUS_MALFORMEDREQUEST
-
非法确认请求
- RESPONSE_STATUS_SIGREQUIRED
-
您必须签名请求并重新提交
- RESPONSE_STATUS_SUCCESSFUL
-
Response
具有有效的确认 - RESPONSE_STATUS_TRYLATER
-
稍后重试
- RESPONSE_STATUS_UNAUTHORIZED
-
您的请求未经授权。
- REVOKED_STATUS_AFFILIATIONCHANGED
-
证书主体的名称或其他信息已更改
- REVOKED_STATUS_CACOMPROMISE
-
此 CA 证书因密钥泄露而被吊销
- REVOKED_STATUS_CERTIFICATEHOLD
-
证书处于暂停状态
- REVOKED_STATUS_CESSATIONOFOPERATION
-
不再需要该证书
- REVOKED_STATUS_KEYCOMPROMISE
-
该证书因密钥泄露而被吊销
- REVOKED_STATUS_NOSTATUS
-
该证书因未知原因被吊销
- REVOKED_STATUS_REMOVEFROMCRL
-
该证书之前处于暂停状态,现在应从 CRL 中删除
- REVOKED_STATUS_SUPERSEDED
-
该证书被新证书取代
- REVOKED_STATUS_UNSPECIFIED
-
该证书因未指定的原因被吊销
- TRUSTOTHER
-
不要验证其他证书
- V_CERTSTATUS_GOOD
-
表示该证书未被吊销,但这并不一定意味着该证书已颁发,或者此响应在证书的有效间隔内
- V_CERTSTATUS_REVOKED
-
表示该证书已被永久或临时吊销(处于暂停状态)。
- V_CERTSTATUS_UNKNOWN
-
表示响应者不知道所请求的证书。
- V_RESPID_KEY
-
响应者 ID 基于公钥。
- V_RESPID_NAME
-
响应者 ID 基于密钥名称。