gpt4 book ai didi

ruby - 如何以编程方式检查证书是否已被吊销?

转载 作者:数据小太阳 更新时间:2023-10-29 07:11:37 24 4
gpt4 key购买 nike

我正在开发一个 xcode 自动构建系统。在执行一些预构建验证时,我想检查指定的证书文件是否已被撤销。我了解 security verify-cert 验证其他证书属性但不验证吊销。我如何检查撤销?

我正在用 Ruby 编写构建系统,但我对任何语言的想法都持开放态度。

我阅读了这个答案 ( Openssl - How to check if a certificate is revoked or not ),但指向底部的链接 ( Does OpenSSL automatically handle CRLs (Certificate Revocation Lists) now? ) 进入的 Material 对我的目的来说有点过于复杂(用户上传已撤销的证书是一个极端的情况)。是否有更简单/面向 ruby​​ 的方法来检查撤销?

提前致谢!

最佳答案

检查证书是否被吊销可能是一个复杂的过程。首先,您必须查找 CDP 或 OCSP AIA,然后发出请求、解析响应并检查响应是否由有权响应相关证书的 CA 签署。如果它是 CRL,则您需要查看您正在检查的证书的序列号是否出现在列表中。如果是 OCSP,那么您需要查看是否收到了“良好”响应(与未知、已撤销或任何各种 OCSP 响应器错误(如未授权)相对)。此外,您可能希望验证证书是否在其有效期内并链接到受信任的根。最后,您还应该对每个中间体进行吊销检查,并根据 Mozilla/Apple/Google/Microsoft 维护的明确黑名单检查证书的指纹。

我不知道有任何 Ruby 库可以为您自动执行吊销检查过程(最终我希望将其添加到 r509 中),但考虑到您更具体的用例,这里有一些未经测试的代码应该会为您指明正确的方向方向。

require 'r509'
require 'net/http'
cert = R509::Cert.load_from_file("some_iphone_cert.pem")
crl_uri = cert.crl_distribution_points.crl.uris[0]
crl = Net::HTTP.get_response(URI(crl_uri)) # you may need to follow redirects here, but let's assume you got the CRL.
# Also note that the Apple WWDRCA CRL is like 28MB so you may want to cache this damned thing. OCSP would be nicer but it's a bit trickier to validate.
parsed_crl = R509::CRL::SignedList.new(crl)
if not parsed_crl.verify(cert.public_key)
raise StandardError, "Invalid CRL for certificate"
end
if parsed_crl.revoked?(cert.serial)
puts 'revoked'
end

不幸的是,由于 Apple WWDRCA CRL 的巨大尺寸(~680k 条目),使用 r509 当前的 HashMap 模型,此检查可能会非常慢。

如果您有兴趣深入了解 OCSP 路径,我也可以写下如何在 Ruby 中生成 OCSP 请求/解析响应。

编辑:看来我拥有的 iPhone 开发人员证书不包含嵌入式 OCSP AIA,因此吊销检查的唯一选择是通过上面介绍的 CRL 分发点。

Edit2:哦,为什么不呢,让我们在 Ruby 中进行 OCSP 检查吧!为此,我们需要证书及其颁发证书。你不能为此使用 WWDRCA 证书,所以只需从你最喜欢的网站上获取一个。我正在使用自己的网站。

require 'net/http'
require 'r509'
cert = R509::Cert.load_from_file("my_website.pem")
# get the first OCSP AIA URI. There can be more than one
# (degenerate example!)
ocsp_uri = cert.aia.ocsp.uris[0]
issuer = R509::Cert.load_from_file("my_issuer.pem")
cert_id = OpenSSL::OCSP::CertificateId.new(cert.cert,issuer.cert)
request = OpenSSL::OCSP::Request.new
request.add_certid(cert_id)
# we're going to make a GET request per RFC 5019. You can also POST the
# binary DER encoded version if you're more of an RFC 2560 partisan
request_uri = URI(ocsp_uri+"/"+URI.encode_www_form_component(req_pem.strip)
http_response = Net::HTTP.get_response(request_uri)
if http_response.code != "200"
raise StandardError, "Invalid response code from OCSP responder"
end
response = OpenSSL::OCSP::Response.new(http_response.body)
if response.status != 0
raise StandardError, "Not a successful status"
end
if response.basic[0][0].serial != cert.serial
raise StandardError, "Not the same serial"
end
if response.basic[0][1] != 0 # 0 is good, 1 is revoked, 2 is unknown.
raise StandardError, "Not a good status"
end
current_time = Time.now
if response.basic[0][4] > current_time or response.basic[0][5] < current_time
raise StandardError, "The response is not within its validity window"
end
# we also need to verify that the OCSP response is signed by
# a certificate that is allowed and chains up to a trusted root.
# To do this you'll need to build an OpenSSL::X509::Store object
# that contains the certificate you're checking + intermediates + root.
store = OpenSSL::X509::Store.new
store.add_cert(cert.cert)
store.add_cert(issuer.cert) #assuming issuer is a trusted root here, but in reality you'll need at least one more certificate
if response.basic.verify([],store) != true
raise StandardError, "Certificate verification error"
end

上面的示例代码忽略了处理许多可能的边缘情况,因此它应该被视为一个起点。祝你好运!

关于ruby - 如何以编程方式检查证书是否已被吊销?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16244084/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com