54

使用 PHP 获取网站 SSL 证书信息

 3 years ago
source link: https://demokn.com/posts/get-ssl-certificate-info-from-a-remote-server-with-php/index.html?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

使用 PHP 获取网站 SSL 证书信息

Published on May 25, 2020

前两天,有用户反馈网站突然打不开了,看了一下用户给的截图,应该是网站的证书过期了。 赶紧爬起来更新了一下证书。为了避免再次发生这种尴尬的事情,想着写一个简单的脚本, 监控网站的证书到期时间,以便提醒自己及时更新证书。

因为自己平时还是和 php 打交道比较多,也有现成的短信、邮件、企业微信等通知方式可用, 所以还是决定用 php 来实现。 关于如何使用PHP获取网站的SSL证书,经过简单的搜索和尝试,还是比较简单的,直接附上代码:

$url = 'https://www.httpbin.org/';
$host = parse_url($url, PHP_URL_HOST);
$streamContext = stream_context_create(['ssl' => ['capture_peer_cert' => true]]);
$socket = stream_socket_client(
    'ssl://'.$host.':443',
    $errorNo,
    $errorMessage,
    30,
    STREAM_CLIENT_CONNECT,
    $streamContext
);
if ($socket === false) {
    echo "[ERROR] Failed to open socket connection: {$errorNo} - {$errorMessage}".PHP_EOL;
    exit(1);
}
$parameters = stream_context_get_params($socket);
$certificate = openssl_x509_parse($parameters['options']['ssl']['peer_certificate']);
print_r($certificate);

解析后的证书信息如下:

[
    'name' => '/CN=httpbin.org',
    'subject' => [
        'CN' => 'httpbin.org',
    ],
    'hash' => '5a356b71',
    'issuer' => [
        'C' => 'US',
        'O' => 'Amazon',
        'OU' => 'Server CA 1B',
        'CN' => 'Amazon',
    ],
    'version' => 2,
    'serialNumber' => '15511154429359216763915851913648262204',
    'serialNumberHex' => '0BAB56F52FC9F721C8C35BFC58E9CC3C',
    'validFrom' => '200118000000Z',
    'validTo' => '210218120000Z',
    'validFrom_time_t' => 1579305600,
    'validTo_time_t' => 1613649600,
    'signatureTypeSN' => 'RSA-SHA256',
    'signatureTypeLN' => 'sha256WithRSAEncryption',
    'signatureTypeNID' => 668,
    'purposes' => [
        1 => [
            true,
            false,
            'sslclient',
        ],
        2 => [
            true,
            false,
            'sslserver',
        ],
        3 => [
            true,
            false,
            'nssslserver',
        ],
        4 => [
            false,
            false,
            'smimesign',
        ],
        5 => [
            false,
            false,
            'smimeencrypt',
        ],
        6 => [
            false,
            false,
            'crlsign',
        ],
        7 => [
            true,
            true,
            'any',
        ],
        8 => [
            true,
            false,
            'ocsphelper',
        ],
        9 => [
            false,
            false,
            'timestampsign',
        ],
    ],
    'extensions' => [
        'authorityKeyIdentifier' => "keyid:59:A4:66:06:52:A0:7B:95:92:3C:A3:94:07:27:96:74:5B:F9:3D:D0\n",
        'subjectKeyIdentifier' => '4D:47:D7:1B:DA:3A:E5:FB:D0:31:40:CA:CE:35:D6:54:B9:C8:EF:A5',
        'subjectAltName' => 'DNS:httpbin.org, DNS:*.httpbin.org',
        'keyUsage' => 'Digital Signature, Key Encipherment',
        'extendedKeyUsage' => 'TLS Web Server Authentication, TLS Web Client Authentication',
        'crlDistributionPoints' => "
         \n
         Full Name:\n
           URI:http://crl.sca1b.amazontrust.com/sca1b.crl\n
         ",
        'certificatePolicies' => "
         Policy: 2.16.840.1.114412.1.2\n
         Policy: 2.23.140.1.2.1\n
         ",
        'authorityInfoAccess' => "
         OCSP - URI:http://ocsp.sca1b.amazontrust.com\n
         CA Issuers - URI:http://crt.sca1b.amazontrust.com/sca1b.crt\n
         ",
        'basicConstraints' => 'CA:FALSE',
        'ct_precert_scts' => "
         Signed Certificate Timestamp:\n
             Version   : v1 (0x0)\n
             Log ID    : EE:4B:BD:B7:75:CE:60:BA:E1:42:69:1F:AB:E1:9E:66:\n
                         A3:0F:7E:5F:B0:72:D8:83:00:C4:7B:89:7A:A8:FD:CB\n
             Timestamp : Jan 18 01:26:21.019 2020 GMT\n
             Extensions: none\n
             Signature : ecdsa-with-SHA256\n
                         30:45:02:21:00:81:00:82:78:B4:00:81:AD:D1:F0:07:\n
                         86:67:18:81:93:CB:7F:FD:17:1B:99:F4:62:28:1E:07:\n
                         D7:E5:18:DE:7D:02:20:79:76:3E:C7:BA:16:42:62:12:\n
                         85:70:AB:05:27:6A:79:36:17:AE:CC:50:71:61:3A:66:\n
                         90:32:43:17:2C:75:45\n
         Signed Certificate Timestamp:\n
             Version   : v1 (0x0)\n
             Log ID    : 87:75:BF:E7:59:7C:F8:8C:43:99:5F:BD:F3:6E:FF:56:\n
                         8D:47:56:36:FF:4A:B5:60:C1:B4:EA:FF:5E:A0:83:0F\n
             Timestamp : Jan 18 01:26:21.098 2020 GMT\n
             Extensions: none\n
             Signature : ecdsa-with-SHA256\n
                         30:45:02:20:10:CC:62:29:B6:B0:5F:1E:1E:95:B5:67:\n
                         BF:F2:43:59:62:4F:06:BC:21:14:A3:89:D0:5D:F5:95:\n
                         48:C1:EE:A6:02:21:00:EC:33:CE:4D:A4:60:73:F7:07:\n
                         DC:EC:C8:19:2B:BA:74:B6:9E:7B:91:7F:61:19:26:0B:\n
                         D4:E2:91:68:96:4C:2F
         ",
    ],
]

可以看到证书信息中的 validTo_time_t 就是证书到期时间。简单的配合 CRONTAB 每天检查一遍,就可以提前通知自己“证书即将到期,请及时更新”。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK