【问题标题】:How to get SSL certificate info with CURL in PHP?如何在 PHP 中使用 CURL 获取 SSL 证书信息?
【发布时间】:2011-03-06 02:15:22
【问题描述】:

我希望能够使用 CURL 读取 SSL 证书信息。 从 Linux 控制台我得到这个响应头:

GET https://www.google.com/ -ed
Cache-Control: private, max-age=0
Connection: close
Date: Sun, 20 Jun 2010 21:34:12 GMT
Server: gws
Content-Type: text/html; charset=ISO-8859-1
Expires: -1
Client-Date: Sun, 20 Jun 2010 21:34:18 GMT
Client-Peer: 66.102.13.106:443
Client-Response-Num: 1
Client-SSL-Cert-Issuer: /C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
Client-SSL-Cert-Subject: /C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
Client-SSL-Cipher: RC4-SHA
Client-SSL-Warning: Peer certificate not verified
Set-Cookie: PREF=ID=4d56960f6e3ad831:TM=1277069652:LM=1277069652:S=GF-w8Yc-_61NBzzJ; expires=Tue, 19-Jun-2012 21:34:12 GMT; path=/; domain=.google.com
Title: Google
X-XSS-Protection: 1; mode=block

但使用 CURL 时,标题要短得多:

HTTP/1.1 200 OK
Date: Sun, 20 Jun 2010 21:39:07 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=UTF-8
Set-Cookie: PREF=ID=2d4fb1c933eebd09:TM=1277069947:LM=1277069947:S=6_TgGKzD0rM4IWms; expires=Tue, 19-Jun-2012 21:39:07 GMT; path=/; domain=.google.com
Server: gws
X-XSS-Protection: 1; mode=block
Transfer-Encoding: chunked

是否有可能获得这些信息,带有 CURL 或其他 PHP 函数的完整标题?

【问题讨论】:

    标签: php ssl curl https


    【解决方案1】:

    没有。 编辑CURLINFO_CERTINFO 选项已添加到 PHP 5.3.2。见http://bugs.php.net/49253

    显然,您的代理在响应标头中向您提供了该信息。如果你想依赖它,你可以使用 curl 的 CURLOPT_HEADER optiontrue 在输出中包含标题。

    但是,要在不依赖某些代理的情况下检索证书,您必须这样做

    <?php
    $g = stream_context_create (array("ssl" => array("capture_peer_cert" => true)));
    $r = fopen("https://www.google.com/", "rb", false, $g);
    $cont = stream_context_get_params($r);
    var_dump($cont["options"]["ssl"]["peer_certificate"]);
    

    您可以使用 OpenSSL 扩展来操作 $cont["options"]["ssl"]["peer_certificate"] 的值。

    EDIT:这个选项更好,因为它实际上并不发出 HTTP 请求,也不需要allow_url_fopen

    <?php
    $g = stream_context_create (array("ssl" => array("capture_peer_cert" => true)));
    $r = stream_socket_client("ssl://www.google.com:443", $errno, $errstr, 30,
        STREAM_CLIENT_CONNECT, $g);
    $cont = stream_context_get_params($r);
    var_dump($cont["options"]["ssl"]["peer_certificate"]);
    

    【讨论】:

    • 所以我需要指令“allow_url_fopen”来获取证书信息?
    • BTW:为什么你认为这个连接是通过代理服务器的? CURLOPT_HEADER 已设置。但标题似乎不完整
    • @Radek Suski 因为谷歌不发送这样的Client-* 标头。
    • @Rad 我还包括一个不需要allow_url_fopen的选项。
    • @Artefacto:非常感谢。它工作得很好,并且使用 openssl_x509_parse 我能够解析证书。 @Chris:我也尝试过获取我的服务器的证书,但它也不起作用。有趣的是,函数 curl_getinfo 还返回一个名为“certinfo”的数组,该数组始终为空。
    【解决方案2】:

    在 php 和 curl 中执行此操作:

    【讨论】:

    • 我的例子需要php 5.3.2,SSL证书信息在$str中,HTTP headers在$result中。
    • 这是我需要检查的解决方案,不仅要检查 SSL 证书是否存在,还要检查它是否有任何错误。谢谢!
    • 只是补充一点,$info = curl_getinfo($ch) 会将证书信息设置在 $info['certinfo'] 下。
    • 即使不推荐,我也必须设置(对于少数主机,类似代码不起作用)ssl 选项"verify_peer" =&gt; false,否则我无法获取证书数据全部。
    【解决方案3】:

    您将使用stream_context_get_params 将证书作为资源获取。将该资源插入$certinfo = openssl_x509_parse($cert['options']['ssl']['peer_certificate']); 以获取更多证书信息。

    $url = "http://www.google.com";
    $orignal_parse = parse_url($url, PHP_URL_HOST);
    $get = stream_context_create(array("ssl" => array("capture_peer_cert" => TRUE)));
    $read = stream_socket_client("ssl://".$orignal_parse.":443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $get);
    $cert = stream_context_get_params($read);
    $certinfo = openssl_x509_parse($cert['options']['ssl']['peer_certificate']);
    print_r($certinfo);
    

    示例结果

    Array
    (
        [name] => /C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
        [subject] => Array
            (
                [C] => US
                [ST] => California
                [L] => Mountain View
                [O] => Google Inc
                [CN] => www.google.com
            )
    
        [hash] => dcdd9741
        [issuer] => Array
            (
                [C] => US
                [O] => Google Inc
                [CN] => Google Internet Authority G2
            )
    
        [version] => 2
        [serialNumber] => 3007864570594926146
        [validFrom] => 150408141631Z
        [validTo] => 150707000000Z
        [validFrom_time_t] => 1428498991
        [validTo_time_t] => 1436223600
        [purposes] => Array
            (
                [1] => Array
                    (
                        [0] => 1
                        [1] => 
                        [2] => sslclient
                    )
    
                [2] => Array
                    (
                        [0] => 1
                        [1] => 
                        [2] => sslserver
                    )
    
                [3] => Array
                    (
                        [0] => 1
                        [1] => 
                        [2] => nssslserver
                    )
    
                [4] => Array
                    (
                        [0] => 
                        [1] => 
                        [2] => smimesign
                    )
    
                [5] => Array
                    (
                        [0] => 
                        [1] => 
                        [2] => smimeencrypt
                    )
    
                [6] => Array
                    (
                        [0] => 1
                        [1] => 
                        [2] => crlsign
                    )
    
                [7] => Array
                    (
                        [0] => 1
                        [1] => 1
                        [2] => any
                    )
    
                [8] => Array
                    (
                        [0] => 1
                        [1] => 
                        [2] => ocsphelper
                    )
    
            )
    
        [extensions] => Array
            (
                [extendedKeyUsage] => TLS Web Server Authentication, TLS Web Client Authentication
                [subjectAltName] => DNS:www.google.com
                [authorityInfoAccess] => CA Issuers - URI:http://pki.google.com/GIAG2.crt
    OCSP - URI:http://clients1.google.com/ocsp
    
                [subjectKeyIdentifier] => FD:1B:28:50:FD:58:F2:8C:12:26:D7:80:E4:94:E7:CD:BA:A2:6A:45
                [basicConstraints] => CA:FALSE
                [authorityKeyIdentifier] => keyid:4A:DD:06:16:1B:BC:F6:68:B5:76:F5:81:B6:BB:62:1A:BA:5A:81:2F
    
                [certificatePolicies] => Policy: 1.3.6.1.4.1.11129.2.5.1
    
                [crlDistributionPoints] => URI:http://pki.google.com/GIAG2.crl
    
            )
    
    )
    

    【讨论】:

    • 这是一个比接受的答案更好的答案,因为缺少关键行 $certinfo = openssl_x509_parse($cert['options']['ssl']['peer_certificate']); 我需要检查有关我的证书的不同详细信息
    • 这是我需要的解决方案,但有一点改动。我将使用它来检查 localhost 上的证书有效期(因此证书对这个“域”无效),所以我需要更改:$get = stream_context_create(array("ssl" =&gt; array("capture_peer_cert" =&gt; TRUE)));$get = stream_context_create(array("ssl" =&gt; array("capture_peer_cert" =&gt; TRUE, "verify_peer_name" =&gt; FALSE)));
    • 当你需要全链时,使用capture_peer_cert_chainpeer_certificate_chain
    • 即使不推荐,我也必须设置(对于少数主机,类似代码不起作用)ssl 选项"verify_peer" =&gt; false,否则我无法获取证书数据全部。
    • 我使用这段代码已经有一段时间了。但截至 2021 年 10 月 1 日 LetsEncrypt 根到期后,php 不再能够连接到使用 LetsEncrypt 证书的域。现在,我已经手动将他们的根证书添加到我的操作系统中,现在浏览器和 curl 可以正常工作,但 PHP 仍然没有。 PHP 是否保留自己的根证书存储,而忽略操作系统的根?它是如何工作的?
    【解决方案4】:

    这段代码 sn-p 没有专门使用 curl,但它检索并打印远程证书文本(可以使用各种 openssl_ 函数进行操作以返回您想要的任何详细信息)

    $g = stream_context_create (array("ssl" => array("capture_peer_cert" => true)));
    $r = fopen("https://somesite/my/path/", "rb", false, $g);
    $cont = stream_context_get_params($r);
    openssl_x509_export($cont["options"]["ssl"]["peer_certificate"],$cert);
    print $cert;
    

    输出:

    -----BEGIN CERTIFICATE-----
    ...certificate content...
    -----END CERTIFICATE-----
    

    【讨论】:

      【解决方案5】:

      这可以解决问题

      [mulhasan@sshgateway-01 ~]$ curl --insecure -v https://yourdomain.com 2>&1 | awk 'BEGIN { cert=0 } /^\* SSL connection/ { cert=1 } /^\*/ { if (cert) print }'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-07-07
        • 2011-12-13
        • 2015-09-25
        • 1970-01-01
        • 2019-02-10
        • 2014-06-16
        • 2018-05-29
        相关资源
        最近更新 更多