PHP探针能否检测SSL证书状态_PHP探针检测SSL证书方法【技巧】

PHP探针无法直接检测SSL证书状态,仅能确认OpenSSL扩展是否启用及当前请求是否为HTTPS;真正检测需用stream_socket_client或cURL主动连接并解析证书有效期等信息。

php探针能否检测ssl证书状态_php探针检测ssl证书方法【技巧】

PHP探针本身不直接检测SSL证书状态,它只能告诉你服务器是否启用了OpenSSL扩展、是否支持HTTPS协议,但无法主动连接远程站点并解析其证书有效期、链完整性或域名匹配问题——这些必须由你主动发起HTTPS请求并处理响应才能获得。

PHP探针能查到的SSL基础信息

典型PHP探针(如雅黑探针、OneBase探针)会调用 extension_loaded('openssl')function_exists('openssl_x509_parse') 来判断OpenSSL是否可用;也会读取 $_SERVER['HTTPS']$_SERVER['SERVER_PORT'] === '443' 判断当前页面是否走HTTPS。但这只是“本机环境支持”和“当前请求协议”,和“目标证书是否有效”是两回事。

  • ✅ 能确认:php_openssl.dll 是否已启用(检查 php.ini;extension=php_openssl.dll 是否去掉了分号)
  • ✅ 能看到:当前页面 URL 是 https:// 还是 http://
  • ❌ 不能知道:你调用的 file_get_contents('https://api.example.com') 会不会因证书过期而失败
  • ❌ 不能发现:Nginx 配置漏了中间证书,导致安卓/iOS客户端握手失败

用PHP代码真正检测远程SSL证书状态

要让探针具备“检测证书”能力,得自己补一段逻辑:用 stream_context_create() 建立带证书校验的HTTPS连接,并捕获错误;再用 openssl_x509_parse() 解析证书内容。关键不是“有没有SSL”,而是“连不连得上、证不证得实”。

  • 必须启用 CURLOPT_SSL_VERIFYPEERCURLOPT_SSL_VERIFYHOST(设为 true),否则等于没校验
  • 若系统CA缺失(如 Alpine 容器),需显式指定 CURLOPT_CAINFO 指向 cacert.pem 文件
  • 证书解析后,$parsed['validTo_time_t'] 是Unix时间戳,对比 time() 就能判断是否过期
  • 注意:openssl_x509_parse() 只能解析本地证书文件或从资源中提取的证书,不能直接解析远程URL——得先用 stream_socket_client()cURL 抓取原始证书
function checkRemoteCert($host, $port = 443) {
    $context = stream_context_create([
        'ssl' => [
            'verify_peer' => true,
            'cafile' => '/path/to/cacert.pem',
            'capture_peer_cert' => true,
            'SNI_enabled' => true,
        ]
    ]);
    $socket = @stream_socket_client("tls://{$host}:{$port}", $errno, $errstr, 5, STREAM_CLIENT_CONNECT, $context);
    if (!$socket) return ['error' => "Connection failed: {$errstr} ({$errno})"];

    $params = stream_context_get_params($socket);
    if (!isset($params['options']['ssl']['peer_certificate'])) {
        return ['error' => 'No certificate received'];
    }

    $cert = openssl_x509_parse($params['options']['ssl']['peer_certificate']);
    if (!$cert) return ['error' => 'Failed to parse certificate'];

    return [
        'subject' => $cert['subject']['CN'] ?? 'N/A',
        'issuer' => $cert['issuer']['CN'] ?? 'N/A',
        'expires_at' => date('Y-m-d H:i:s', $cert['validTo_time_t']),
        'expired' => $cert['validTo_time_t'] < time(),
    ];
}

为什么探针里加了检测还是不准?常见坑点

很多自建探针把检测写成“能 file_get_contents('https://baidu.com') 就算通过”,这非常误导——因为默认上下文可能关闭了证书验证,或者系统自动 fallback 到旧TLS版本,掩盖真实问题。

Tellers AI

Tellers AI

Tellers是一款自动视频编辑工具,可以将文本、文章或故事转换为视频。

下载

立即学习PHP免费学习笔记(深入)”;

  • ⚠️ file_get_contents() 默认不校验证书,除非你传入了带 'verify_peer' => truestream_context
  • ⚠️ 使用 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false) 测试通不通,结果为“通”≠“证书正常”,只是绕过了验证
  • ⚠️ 检测时用了 www.example.com,但证书只签了 example.comCURLOPT_SSL_VERIFYHOST 设为 2 才会报错,设为 1false 就漏掉
  • ⚠️ 在Docker Alpine镜像里跑探针,/etc/ssl/certs/ca-certificates.crt 根本不存在,必须手动挂载或指定 CAINFO

真正有用的SSL状态检测,从来不是“探针有没有显示绿色对勾”,而是你明确控制了验证开关、指定了可信CA路径、并解析了证书里的 validTo_time_t 字段——其他都是障眼法。

https://www.php.cn/faq/2009767.html

发表回复

Your email address will not be published. Required fields are marked *