是否可以从任何网站读取PHP中的SSL信息?

时间:2010-08-12 01:30:49

标签: php ssl curl ssl-certificate

我想知道是否有可能使用PHP阅读其他各方提供的有关其SSL证书信息的信息,我已经尝试了很长时间找到它,但是找不到真正的答案。

例如,我在脚本中输入“www.paypal.com”,它将返回以下内容:

  • 授权:VeriSign,Inc
  • 到期日:2011年2月18日(18/02/11)
  • 类型:扩展验证
  • 主持人:www.paypal.com
  • MD5:a8e7o7a8e9e9
  • SHA1:c2a4a1e4e3a2

而且,无论如何都可以获得。我想用PHP编写脚本。

3 个答案:

答案 0 :(得分: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"]) );
?>

答案 1 :(得分:3)

我编写了一个用于获取SSL信息的PHP类:

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类中的“instantiate”方法]。谢谢......

答案 2 :(得分:2)

PHP的OpenSSL函数如openssl_x509_parse应该可以帮助你。