Я хотел бы иметь возможность читать информацию сертификата 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?
Нет. EDIT : в PHP 5.3.2 добавлена опция CURLINFO_CERTINFO
. См. http://bugs.php.net/49253
По-видимому, эта информация предоставляется вам вашим прокси в заголовках ответов. Если вы хотите положиться на это, вы можете использовать параметр 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"]);
Вы можете манипулировать значением $cont["options"]["ssl"]["peer_certificate"]
с расширением OpenSSL.
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"]);
Вы получите сертификат как ресурс, используя 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 ) )
Для этого в 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); // перемотка назад $ Ул = ''; в то время как (. STRLEN ($ ул = Fread ($ ∥f∥p, 8192)) == 8192); echo $ str; fclose ($ FP); } ?>
Этот фрагмент кода не использует завиток специально, но он извлекает и печатает текст удаленного сертификата (его можно обрабатывать, чтобы возвращать любую деталь, которую вы хотите, с помощью различных функций 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-----