我希望能够使用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函数?
答案 0 :(得分:25)
您将使用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
)
)
答案 1 :(得分:18)
没有。 编辑:PHP 5.3.2中添加了CURLINFO_CERTINFO
选项。见http://bugs.php.net/49253
显然,您的代理在响应标头中提供了这些信息。如果您想依赖它,可以使用curl的CURLOPT_HEADER
option到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"]
的值。
编辑:此选项更好,因为它实际上不会发出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"]);
答案 2 :(得分:17)
要在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 or die("Error:".curl_errno($ch)." ".curl_error($ch)); fseek($fp, 0);//rewind $str=''; while(strlen($str.=fread($fp,8192))==8192); echo $str; fclose($fp); } ?>
答案 3 :(得分:3)
此代码段并未专门使用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 :(得分:-2)
这可以解决问题
[mulhasan@sshgateway-01 ~]$ curl --insecure -v https://yourdomain.com 2>&1 | awk 'BEGIN { cert=0 } /^\* SSL connection/ { cert=1 } /^\*/ { if (cert) print }'