2010-08-12 47 views
5

我想知道是否有可能從其他方使用PHP讀取有關其SSL證書信息的信息,我試着找出它的適用年齡,但沒有找到真正的答案。是否可以從任何網站閱讀PHP中的SSL信息?

例如,我輸入 「www.paypal.com」 到腳本,它會返回以下內容:

  • 管理局:威瑞信公司
  • 截止日期:2011年2月18日(18/02/11)
  • 類型:擴​​展驗證
  • 主持人:www.paypal.com
  • MD5:a8e7o7a8e9e9
  • SHA1:c2a4a1e4e3a2

而且,無論其他可能獲得。我希望PHP中的腳本。

+0

查看http://stackoverflow.com/questions/3081042/how-to-get-ssl-certificate-info-with-curl-in-php/3081093#3081093 – Artefacto 2010-08-12 10:28:03

回答

2

PHP的OpenSSL功能如openssl_x509_parse應該可以幫到你。

+0

我該如何構建它從網站的SSL信息讀取?我不知道如何從第三方網站獲取SSL信息。 – 2010-08-12 05:01:17

+0

這個函數的壞處是PHP在5.6之前的舊版本中存在一個遠程代碼執行漏洞,標識爲CVE-2013-6420。有關複雜的方式,請參閱https://github.com/composer/ca-bundle/blob/master/src/CaBundle.php#L184,以瞭解Composer試圖識別它運行的PHP是否安全。 – Sven 2016-07-11 13:51:01

6
 
<?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); 
print_r(openssl_x509_parse($cont["options"]["ssl"]["peer_certificate"])); 
?> 
3

我寫了一個PHP類用於獲取SSL信息:

class SSL { 

    public $domain, $validFrom, $validTo, $issuer, $validity, $validitytot, $crtValRemaining; 

    private static function instantiate($url, $info) { 
     $obj = new static; 
     $obj->domain = $url; 
     $obj->validFrom = $info['validFrom']; 
     $obj->validTo = $info['validTo']; 
     $obj->issuer = $info['issuer']; 
     $obj->validity = $info['validity']; 
     $obj->validitytot = $info['validitytot']; 
     $obj->crtValRemaining = $info['crtValRemaining']; 

     return $obj; 
    } 

    public static function getSSLinfo($url) { 
     $ssl_info = []; 
     $certinfo = static::getCertificateDetails($url); 
     $validFrom_time_t_m = static::dateFormatMonth($certinfo['validFrom_time_t']); 
     $validTo_time_t_m = static::dateFormatMonth($certinfo['validTo_time_t']); 

     $validFrom_time_t = static::dateFormat($certinfo['validFrom_time_t']); 
     $validTo_time_t = static::dateFormat($certinfo['validTo_time_t']); 
     $current_t = static::dateFormat(time()); 

     $ssl_info['validFrom'] = $validFrom_time_t_m; 
     $ssl_info['validTo'] = $validTo_time_t_m; 
     $ssl_info['issuer'] = $certinfo['issuer']['O']; 

     $ssl_info['validity'] = static::diffDate($current_t, $validTo_time_t)." days"; 
     $ssl_info['validitytot'] = (static::diffDate($validFrom_time_t, $validTo_time_t)-1).' days'; 

     $ssl_info['crtValRemaining'] =$certinfo['validTo_time_t']; 

     return static::instantiate($url, $ssl_info); // return an object 
    } 

    private static function getCertificateDetails($url) { 
     $urlStr = strtolower(trim($url)); 

     $parsed = parse_url($urlStr);// add http:// 
     if (empty($parsed['scheme'])) { 
      $urlStr = 'http://' . ltrim($urlStr, '/'); 
     } 
     $orignal_parse = parse_url($urlStr, 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']); 
     return $certinfo; 
    } 

    private static function dateFormat($stamp) { 
     return strftime("%Y-%m-%d", $stamp); 
    } 

    private static function dateFormatMonth($stamp) { 
     return strftime("%Y-%b-%d", $stamp); 
    } 

    private static function diffDate($from, $to) { 
     $date1=date_create($from); 
     $date2=date_create($to); 
     $diff=date_diff($date1,$date2); 
     return ltrim($diff->format("%R%a"), "+"); 
    } 

} 

EX:

$certInfo = SSL::getSSLinfo('stackoverflow.com'); 
echo $certInfo->validFrom .'<br>'; 
echo $certInfo->validTo .'<br>'; 
echo $certInfo->issuer .'<br>'; 
echo $certInfo->validity .'<br>'; 
echo $certInfo->validitytot .'<br>'; 
echo $certInfo->crtValRemaining .'<br>'; 

[請務必瞭解SSL類裏面的 「實例」 方法。謝謝...

+1

這應該是被接受的答案 - 適用於所有測試用例 – Arthur 2017-10-17 03:33:49