douya2006 2015-11-27 17:36
浏览 42

检查与PHP的SSL连接:拦截警告或无论如何手动处理各种方案

I want to get the details of digital certificate of a domain, if the digital certificate exists.

I want to build something like the Google Chrome security indicator.

To get the details of the digital certificate, I use this code:

    $cacert = $this->getParameter('kernel.root_dir') . '/../src/AppBundle/Resources/public/security/cacert.pem';

    $host = 'www.mywebsite.it';

    $contextOptions = [
        'http' => [
            'ignore_errors' => true
        ],
        'ssl' => [
            'verify_peer' => false,
            'cafile' => $cacert,
            //'peer_name' => $host,
            'ciphers' => 'HIGH',
            'disable_compression' => true,
            'capture_peer_cert' => true,
            'capture_peer_cert_chain' => true
        ],
    ];

    $context = stream_context_create($contextOptions);

    $domain = preg_replace('/(http:\/\/)|(https:\/\/)/', '', $host);
    $socket = stream_socket_client(
        'ssl://' . $domain . ':443',
        $errno,
        $errstr,
        30,
        STREAM_CLIENT_CONNECT,
        $context
        );

    if (!$socket) {
        echo "$errstr ($errno)<br />
";
    }

    $params = stream_context_get_params($socket);

    $cert_resource = $params['options']['ssl']['peer_certificate'];
    $cert = openssl_x509_parse($cert_resource);

    dump($cert);die;

This code was taken from here.

What I'd like to achieve is a script that can behave like the Google Chrome SSL certificate Checker, so I'd like to know if a website is secure or not and, if yes, how much it is. Details about Google Chrome security indicators can be found here.

THE PROBLEMS/QUESTIONS

1) stream_socket_client() raises some Warnings if problems happen instead of using \Exceptions. So, how can I intercept Warnings to understand what is happening? Is the custom error handler the only solution as suggested here, here, here and here?

As you can see from the code above, I've also set the http ignore_errors property to false, but this seems not working (see point number 2, the following). This possible solution was suggested here.

2) My domain hasn't a digital certificate, but my server has one, so, when I try to get the certificate, I get the following error:

Warning: stream_socket_client(): Peer certificate CN='ssl.my.server.com' did not match expected CN='www.mydomain.it'

So, I cannot get the certificate details because the connection stops before I get them. How can I get anyway the details of the certificate? Is this connection secure or not? Is the difference with a green Chrome bar only the fact that the certificate is for a domain different than the one called? But this connection is secure or not?

3) I've tried to get the certificate details of a domain without a certificate (also the server hasn't one) and I get this warning:

Warning: stream_socket_client(): unable to connect to ssl://www.non-secure-domain.com:443 (Operation timed out)

Is this error sufficient to say the domain hasn't a digital certificate at all? Which is the difference between this error and the one I get at the point 2?

4) The last question: as it is possible to connect to a remote host also via cURL, should have I to use cURL or it sufficient stream_socket_client()? Which is the difference between the two for my use case (getting the digital certificate details)?

Thank you for your advices :)

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 matlab实现基于主成分变换的图像融合。
    • ¥15 对于相关问题的求解与代码
    • ¥15 ubuntu子系统密码忘记
    • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
    • ¥15 保护模式-系统加载-段寄存器
    • ¥15 电脑桌面设定一个区域禁止鼠标操作
    • ¥15 求NPF226060磁芯的详细资料
    • ¥15 使用R语言marginaleffects包进行边际效应图绘制
    • ¥20 usb设备兼容性问题
    • ¥15 错误(10048): “调用exui内部功能”库命令的参数“参数4”不能接受空数据。怎么解决啊