lyquidity / requester
使用在线证书状态协议(OCSP)查询HTTPS证书吊销状态,并向时间戳权威机构(TSA)发起请求的库
Requires
- php: >=7.4.0
- ext-curl: *
- ext-gmp: *
- ext-openssl: *
README
这是由 #mlocati 修改的 OCSP 仓库版本,并增加了时间戳权威机构(TSA)类。
修改是为了支持项目 OCSP 响应器。其中变化包括添加新的 ASN.1 标签和移除对 phpseclib 的依赖。
此仓库包含一个PHP库,可以帮助您通过在线证书状态协议(OCSP)检查HTTPS证书是否被吊销。
此库不需要调用系统工具(如OpenSSL)的 exec
调用:它是一个纯PHP库。
此库不包含任何网络相关辅助工具:您必须使用自己的传输库(cURL、Zend HTTP、Guzzle等)。
检查HTTPS证书需要
- 要检查的证书,格式为PEM(即以`-----BEGIN CERTIFICATE-----`开始的文本文件),或DER格式(即二进制文件)
- 颁发者证书,即提供HTTPS证书的认证机构证书
- 由认证机构提供的用于OCSP调用的URL(即所谓的
OCSR 响应器URL
)
从HTTPS URL获取证书和颁发者证书
您可以使用以下代码从HTTPS URL获取HTTPS证书和颁发者证书
$hCurl = curl_init($url); curl_setopt($hCurl, CURLOPT_RETURNTRANSFER, false); curl_setopt($hCurl, CURLOPT_CUSTOMREQUEST, 'HEAD'); curl_setopt($hCurl, CURLOPT_NOBODY, true); curl_setopt($hCurl, CURLOPT_CERTINFO, true); curl_exec($hCurl); $certInfo = curl_getinfo($hCurl, CURLINFO_CERTINFO); $certificate = $certInfo[0]['Cert']; $issuerCertificate = $certInfo[1]['Cert'];
从证书中获取颁发者证书
HTTPS证书通常包含一个URL,您可以在其中找到证书颁发者证书。
您可以使用此代码提取此URL,前提是 '/path/to/certificate'
是包含您的HTTPS证书的本地文件的路径
$certificateLoader = new \Ocsp\CertificateLoader(); $certificate = $certificateLoader->fromFile('/path/to/certificate'); $certificateInfo = new \Ocsp\CertificateInfo(); $urlOfIssuerCertificate = $certificateInfo->extractIssuerCertificateUrl($certificate);
此时, $urlOfIssuerCertificate
将包含可以从中下载颁发者证书的URL(如果它是空字符串,则表示颁发者证书URL未包含在您的证书中)。
获取OCSP响应器URL
为了检查证书是否有效,我们需要知道由颁发证书的机构提供的URL,该URL可以用于检查证书是否已被吊销。
此URL可能包含在HTTPS证书本身中。
要获取它,您可以使用以下代码(假设 '/path/to/certificate'
是包含您的HTTPS证书的本地文件的路径)
$certificateLoader = new \Ocsp\CertificateLoader(); $certificate = $certificateLoader->fromFile('/path/to/certificate'); $certificateInfo = new \Ocsp\CertificateInfo(); $ocspResponderUrl = $certificateInfo->extractOcspResponderUrl($certificate);
检查证书是否被吊销
一旦您有了HTTPS证书、颁发者证书和OCSP响应器URL,您就可以检查HTTPS证书是否已被吊销,或者它是否仍然有效。
为此,您必须编写一些代码(这里我们使用cURL,但您可以使用任何其他传输库)
$certificateLoader = new \Ocsp\CertificateLoader(); $certificateInfo = new \Ocsp\CertificateInfo(); $ocsp = new \Ocsp\Ocsp(); // Load the HTTPS certificate and the issuer certificate $certificate = $certificateLoader->fromFile('/path/to/certificate'); $issuerCertificate = $certificateLoader->fromFile('/path/to/issuer/certificate'); // Extract the relevant data from the two certificates $requestInfo = $certificateInfo->extractRequestInfo($certificate, $issuerCertificate); // Build the raw body to be sent to the OCSP Responder URL $requestBody = $ocsp->buildOcspRequestBodySingle($requestInfo); // Actually call the OCSP Responder URL (here we use cURL, you can use any library you prefer) $hCurl = curl_init(); curl_setopt($hCurl, CURLOPT_URL, $ocspResponderUrl); curl_setopt($hCurl, CURLOPT_RETURNTRANSFER, true); curl_setopt($hCurl, CURLOPT_POST, true); curl_setopt($hCurl, CURLOPT_HTTPHEADER, ['Content-Type: ' . \Ocsp\Ocsp::OCSP_REQUEST_MEDIATYPE]); curl_setopt($hCurl, CURLOPT_SAFE_UPLOAD, true); curl_setopt($hCurl, CURLOPT_POSTFIELDS, $requestBody); $result = curl_exec($hCurl); $info = curl_getinfo($hCurl); if ($info['http_code'] !== 200) { throw new \RuntimeException("Whoops, here we'd expect a 200 HTTP code"); } if ($info['content_type'] !== \Ocsp\Ocsp::OCSP_RESPONSE_MEDIATYPE) { throw new \RuntimeException("Whoops, the Content-Type header of the response seems wrong!"); } // Decode the raw response from the OCSP Responder $response = $ocsp->decodeOcspResponseSingle($result);
此时, $response
包含 Ocsp\Response
类的实例
- 如果
$response->isRevoked() === false
,则证书未被吊销 - 如果
$response->isRevoked() === true
,则证书已被吊销(您可以通过调用$response->getRevokedOn()
获取吊销的日期和时间) - 在未知状态下,
$response->isRevoked()
将返回null
异常
在加载证书、创建OCSP响应者的请求体、分析OCSP响应者的响应时可能会出现问题。为了捕捉这些错误,您可以在代码中包含try/catch语句
try { // code } catch (\Ocsp\Exception\Exception $problem) { // handle the error cases }