web-dev-qa-db-ja.com

PHPでCURLを使用してSSL証明書情報を取得する方法

SSL証明書情報をCURLで読み取れるようにしたい。 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関数を使用した完全なヘッダーを取得する可能性はありますか?

23
Radek Suski

いいえ[〜#〜] edit [〜#〜]:_CURLINFO_CERTINFO_オプションがPHP 5.3.2。参照 http://bugs.php.net/4925

どうやら、その情報はプロキシによって応答ヘッダーで提供されています。これに依存したい場合は、curlの _CURLOPT_HEADER_オプションtrueに使用して、ヘッダーを出力に含めることができます。

ただし、プロキシに依存せずに証明書を取得するには、次を実行する必要があります

_<?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"]);
_
19
Artefacto

_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

        )

)
_
28
Intekhab Khan

これをphpとcurlで行うには:

 <?php 
 if($ fp = tmpfile())
 {
 $ ch = curl_init(); 
 curl_setopt($ ch、 CURLOPT_URL、 "https://www.digicert.com/"); 
 curl_setopt($ ch、CURLOPT_STDERR、$ fp); 
 curl_setopt($ ch、CURLOPT_CERTINFO、1); 
 curl_setopt($ ch、CURLOPT_VERBOSE、1); 
 curl_setopt($ ch、CURLOPT_HEADER、1); 
 curl_setopt($ ch、CURLOPT_NOBODY、1); 
 curl_setopt($ ch、CURLOPT_SSL_VERIFYPEER、true); 
 curl_setopt($ ch、CURLOPT_SSL_VERIFYHOST、2); 
 $ result = curl_exec($ ch); 
 curl_errno($ ch)== 0またはdie( "エラー:"。curl_errno($ ch)。 "" .curl_error($ ch)); 
 fseek($ fp、0); // rewind 
 $ str = ''; 
 while(strlen($ str。= fread($ fp、8192))== 8192); 
 echo $ str; 
 fclose($ fp); 
} 
?> 
17
velcrow

このコードスニペットは特に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-----
4
Pancho