文档中心
PHPcURL鑾峰彇HTTPS璇佷功璇﹁В鍘熺悊銆佹柟娉曚笌瀹炴垬妗堜緥
时间 : 2025-09-27 16:29:40浏览量 : 3
为什么需要获取HTTPS证书?

作为一名网络安全工程师,我经常需要检查网站的HTTPS证书信息。想象一下,你就像是一个网站安全"体检医生",而SSL/TLS证书就是网站的"健康证明"。我们需要检查这个证明是否有效、是否过期、是否由可信机构颁发等等。
在PHP中,cURL是一个强大的工具,它就像是一把"瑞士军刀",能帮我们完成各种网络请求任务。今天我要重点讲解如何用PHP cURL这把"军刀"来精确获取HTTPS证书信息。
基础概念快速了解
HTTPS证书就像是网站的身份证,它包含:
- 颁发给谁(域名)
- 由谁颁发(CA机构)
- 有效期
- 公钥信息
- ...等等重要信息
cURL则是一个命令行工具和库,支持多种协议(HTTP/HTTPS/FTP等),PHP内置了对cURL的支持。
PHP cURL获取证书的完整流程
让我们通过一个实际例子来理解整个过程:
```php
// 初始化cURL会话
$ch = curl_init();
// 设置要请求的HTTPS网址
curl_setopt($ch, CURLOPT_URL, "https://example.com");
// 设置为true表示不输出响应内容,只获取头信息
curl_setopt($ch, CURLOPT_NOBODY, true);
// 设置为true表示跟随重定向
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// 设置为2表示验证对等证书和主机名
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
// 设置为2表示严格验证主机名
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
// 设置一个回调函数来接收证书信息
curl_setopt($ch, CURLOPT_CERTINFO, true);
// 执行请求
curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
// 获取证书信息数组
$certInfo = curl_getinfo($ch, CURLINFO_CERTINFO);
print_r($certInfo);
}
// 关闭cURL资源
curl_close($ch);
?>
```
这个代码会输出类似这样的结果:
Array
(
[0] => Array
(
[Subject] => CN=example.com,O=Example Inc,L=San Francisco,ST=California,C=US
[Issuer] => CN=DigiCert SHA2 Secure Server CA,O=DigiCert Inc,C=US
[Version] =>
[Serial Number] =>
[Signature algo] =>
[Start date] => Mar 4 00:00:00 2025 GMT
[Expire date] => Mar 4 12:00:00 2025 GMT
[Public Key algo] =>
)
)
cURL选项详解:安全工程师的配置要点
作为安全从业人员,有几个关键选项需要特别注意:
1. CURLOPT_SSL_VERIFYPEER - "要不要检查对方身份证真伪"
- `true`:验证对方SSL证书(强烈推荐生产环境使用)
- `false`:不验证(仅用于测试环境)
2. CURLOPT_SSL_VERIFYHOST - "要不要核对身份证上的名字"
- `0`:不检查主机名匹配性(不安全)
- `1`:检查公用名(Common Name)存在但不一定匹配(部分安全)
- `2`:严格检查公用名或替代名称匹配(最安全)
3. CURLOPT_CERTINFO - "要不要把对方身份证复印件带回来"
- `true`:收集证书信息到CURLINFO_CERTINFO中
*专业提示*:在生产环境中永远不要禁用SSL验证(CURLOPT_SSL_VERIFYPEER=false),这会使你的应用面临中间人攻击风险!
HTTPS证书链解析实战
一个完整的HTTPS连接通常会涉及多个层级的证书。让我们看看如何解析整个信任链:
function getCertificateChain($url) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CERTINFO => true,
CURLOPT_VERBOSE => true,
CURLOPT_STDERR => $verbose = fopen('php://temp', 'w+')
]);
curl_exec($ch);
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
// 从详细日志中提取完整的PEM格式证书链
preg_match_all('/-BEGIN CERTIFICATE-.*?-END CERTIFICATE-/s', $verboseLog, $matches);
fclose($verbose);
curl_close($ch);
return array_map(function ($cert) {
return openssl_x509_parse(openssl_x509_read("--BEGIN CERTIFICATE--\n".
chunk_split(base64_encode(openssl_x509_fingerprint(openssl_x509_read(
trim(str_replace(['--BEGIN CERTIFICATE--', '--END CERTIFICATE--'], '', $cert))
), 'sha256')),64,"\n").
"--END CERTIFICATE--\n"));
}, $matches[0]);
print_r(getCertificateChain('https://example.com'));
这个高级示例会:
1. 启用详细日志记录(CURLOPT_VERBOSE)
2. 从日志中提取完整的PEM格式证书链(包括中间CA和根CA)
3. 使用OpenSSL函数解析每个证书的详细信息
HTTPS安全检查最佳实践
在实际工作中,我经常使用这些技术进行安全检查:
1. 到期监控:
$certInfo = /*...从curl获取的证书信息...*/;
$expiryDate = strtotime(end(explode(':', $certInfo['Expire date'])));
if ($expiryDate < time() + (30 * 24 * 60 *60)) { //30天内过期警告
sendAlert("网站将在30天内过期!");
2. CA黑名单检查:
$blacklistCAs = ['某些不受信任的CA机构'];
if (in_array(parseIssuerCN($certInfo['Issuer']), $blacklistCAs)) {
blockAccess("该网站使用了不受信任的CA颁发的证书!");
3. 弱签名算法检测:
```php
if (strpos(strtolower($certInfo['Signature algo']), 'sha1') !== false) {
logSecurityEvent("警告:检测到使用不安全的SHA1签名算法!");
PHP cURl与OpenSSL的结合应用
有时我们需要更深入的解析能力,可以结合OpenSSL扩展:
function getCertDetailsWithOpenSSL($url) {
// ...先通过cURl获取原始PEM格式的服务器证书...
// OpenSSL解析示例:
$x509 = openssl_x509_read("--BEGIN CERTIFICATE--\n...\n--END CERTIFICATE--");
return [
'subject' => openssl_x509_parse($x509)['name'],
'issuer' => openssl_x509_parse(x509)['issuer'],
'valid_from' => date('Y-m-d', openssl_x509_parse(x509)['validFrom_time_t']),
'valid_to' => date('Y-m-d', openssl_x509_parse(x509)['validTo_time_t']),
'fingerprint' => openssl_x509_fingerprint(x509),
'extensions' => openssl_x509_parse(x509)['extensions']
];
这种方法可以提供更详细的扩展字段访问能力。
HTTPS连接的常见问题排查技巧
在实际应用中可能会遇到各种问题:
1. 自签名证书错误
```bash
SSL certificate problem: self signed certificate in certificate chain
```
解决方案:
// (仅限测试环境)可以临时跳过验证:
curl_setopt(CURLOPT_SSL_VERIFYPEER, false);
// (生产环境推荐)将自签名CA添加到受信任列表:
curl_setopt(CURLLOT_CAINFO,'/path/to/custom-ca.pem');
2. 主机名不匹配错误
// (临时方案)降低验证级别为1:
curl_setopt(CURLLOT_VALIFYHOSTS ,1);
// (正确方案)确保访问的主机名与CN/SAN匹配:
$correctHostname='real.example.com';
curllot_url,"https://".correctHostname);
curllot_varyhosts ,2);
3.过期的本地CA包问题
解决方案是定期更新本地CA包文件路径。
HTTPS监控系统的实际案例分享
在我的一个客户项目中,我们构建了一个自动化HTTPS监控系统:
核心功能包括:
- 每日自动扫描所有业务域名
- 提前30天提醒即将过期的域名
- 检测不合规的加密算法(TLS <1.2,SHA1等)
- 识别不受信任的CA颁发者
实现核心代码结构如下:
```php
class CertMonitor {
private domains=[];
private db;
public function addDomain(url){/*...*/}
public function runDailyCheck(){
foreach(this->domains as domain){
try{
info=getCertInfo(domain);
this->db->log(info);
if(info->expiresSoon()){
this->alert(info); }
if(!info->isTrusted()){
this->block(info); }
}catch(Exception e){logError(e);} } }
private function getCertInfo(url){
/*使用前面介绍的cURl方法实现*/ }
这套系统帮助客户避免了多次因忘记续费导致的业务中断事故。
HTTPS安全的未来趋势观察
随着网络安全要求的不断提高:
1.TLS版本升级趋势: TLSv1.0/1.1已被广泛弃用,TLSv13成为新标准。在PHP中可以通过以下方式强制要求更高版本的TLS:
``` php
curllot_tls13_only=true; //PHP7+.x支持
curllot_slv_max=CURLL_TLSLV_l3;
2.自动续期革命: Let's Encrypt等免费ACME服务的普及使得90天短期有效期成为新常态。这意味着自动化续期工具变得至关重要。
3.扩展验证(EV)衰退:由于浏览器UI变化和成本考虑,EVCert的使用正在减少,DV/OV成为主流选择.
4.CT日志强制化: Certificate Transparency已成为行业标准要求所有公开信任的TLS证书记录在公共CT日志中.
作为开发者和安全从业者我们需要持续关注这些变化并相应调整我们的代码和实践.
通过本文您应该已经掌握了如何使用PHP cURl全面检查和获取HTTPS网站的安全证照信息。记住在生产环境中永远不要禁用必要的安全检查并且定期更新您的本地可信根存储库(ca-certificates)。
TAG:php curl 获取https 证书,php curl获取cookie,php获取url文件名,php获取ua