2010-06-20 27 views
20

Tôi muốn có thể đọc thông tin chứng chỉ SSL bằng CURL. Từ bàn giao tiếp Linux tôi nhận được tiêu đề này trả lời:Cách nhận thông tin chứng chỉ SSL với CURL trong PHP?

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 

Nhưng với CURL tiêu đề ngắn hơn nhiều:

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 

Có khả năng để có được những thông tin, tiêu đề đầy đủ với CURL hay với một số chức năng PHP khác?

Trả lời

17

No. EDIT: Một tùy chọn CURLINFO_CERTINFO đã được thêm vào PHP 5.3.2. Xem http://bugs.php.net/49253

Dường như thông tin đó được proxy của bạn cung cấp trong tiêu đề phản hồi. Nếu bạn muốn dựa vào đó, bạn có thể sử dụng số CURLOPT_HEADER option của curl để true để bao gồm các tiêu đề trong đầu ra.

Tuy nhiên, để lấy giấy chứng nhận mà không dựa vào một số proxy, bạn phải làm

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

Bạn có thể thao tác các giá trị của $cont["options"]["ssl"]["peer_certificate"] với phần mở rộng OpenSSL.

EDIT: Tùy chọn này là tốt hơn vì nó không thực sự làm cho các yêu cầu HTTP và không đòi hỏi 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"]); 
+0

Vì vậy, tôi sẽ cần chỉ thị "allow_url_fopen" để nhận thông tin chứng chỉ? –

+0

BTW: Tại sao bạn nghĩ rằng kết nối này đang trải qua một máy chủ proxy? CURLOPT_HEADER đã được đặt. Nhưng tiêu đề dường như không hoàn thành –

+0

@Radek Suski Vì google không gửi các tiêu đề 'Client- *' như vậy. – Artefacto

13

Để làm điều này trong php và 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); 
} 
?> 
+0

Bạn có chắc bạn đã đọc câu hỏi của tôi và tất cả những câu trả lời này? –

+2

Ví dụ của tôi yêu cầu php 5.3.2 và thông tin SSL SSL có sẵn trong $ str, tiêu đề HTTP có sẵn trong kết quả $. – velcrow

+0

Đây là giải pháp tôi cần để kiểm tra không chỉ nếu chứng chỉ SSL tồn tại mà còn nếu nó có bất kỳ lỗi nào hay không. Cảm ơn! – armandbertea

17

Bạn sẽ nhận được chứng chỉ dưới dạng tài nguyên sử dụng stream_context_get_params. Cắm tài nguyên đó vào $certinfo = openssl_x509_parse($cert['options']['ssl']['peer_certificate']); để nhận thêm thông tin chứng chỉ.

$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); 

Ví dụ dẫn

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 

     ) 

) 
+2

Đây là câu trả lời tốt hơn câu trả lời được chấp nhận là thiếu dòng khóa '$ certinfo = openssl_x509_parse ($ cert ['options'] ['ssl'] ['peer_certificate']);' mà tôi cần kiểm tra các chi tiết khác nhau về cert –

+0

Đây là giải pháp tôi cần, nhưng với một thay đổi nhỏ. Tôi sẽ sử dụng điều này để kiểm tra thời hạn hiệu lực của cert trên localhost (vì vậy chứng chỉ không hợp lệ cho "miền" này), vì vậy tôi cần thay đổi: '$ get = stream_context_create (mảng (" ssl "=> array (" capture_peer_cert "=> TRUE)));' đến '$ get = stream_context_create (mảng (" ssl "=> mảng (" capture_peer_cert "=> TRUE," verify_peer_name "=> FALSE)));' – Whatts

0

đoạn mã này không được sử dụng curl cụ thể, nhưng nó lấy và in các văn bản giấy chứng nhận từ xa (có thể được chế tác để trả lại bất cứ chi tiết mà bạn muốn sử dụng các chức năng khác nhau 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; 

kết quả đầu ra:

-----BEGIN CERTIFICATE----- 
...certificate content... 
-----END CERTIFICATE----- 
Các vấn đề liên quan