是否可以获取域名(例如www.example.com
)的HTTPS准备情况?
我需要验证一些URL,以确定它们是否具有SSL证书。我知道可以使用$_SERVER['HTTPS']
来检查我们的服务器详细信息,但是如何为其他域名实现相同的功能呢?
非常感谢您的任何帮助。
最后,我得到了以下代码:
$stream = stream_context_create (array("ssl" => array("capture_peer_cert" => true)));
$read = fopen("https://www.example.com", "rb", false, $stream);
$cont = stream_context_get_params($read);
$var = ($cont["options"]["ssl"]["peer_certificate"]);
$result = (!is_null($var)) ? true : false;
如果为域名启用了 HTTPS,则 var_dump($var)
的输出如下所示:resource(4) of type (OpenSSL X.509)
如果不存在,它会返回NULL
。
我已经检查了几个域名。它似乎工作正常。我希望它能帮助到某些人。
此函数不仅会检查域名是否具有SSL证书,还会确认证书是否与请求的域名匹配。
最重要的部分是函数openssl_x509_parse
,它解析证书并将所有细节作为数组返回。
function has_ssl( $domain ) {
$res = false;
$stream = @stream_context_create( array( 'ssl' => array( 'capture_peer_cert' => true ) ) );
$socket = @stream_socket_client( 'ssl://' . $domain . ':443', $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $stream );
// If we got a ssl certificate we check here, if the certificate domain
// matches the website domain.
if ( $socket ) {
$cont = stream_context_get_params( $socket );
$cert_ressource = $cont['options']['ssl']['peer_certificate'];
$cert = openssl_x509_parse( $cert_ressource );
// Expected name has format "/CN=*.yourdomain.com"
$namepart = explode( '=', $cert['name'] );
// We want to correctly confirm the certificate even
// for subdomains like "www.yourdomain.com"
if ( count( $namepart ) == 2 ) {
$cert_domain = trim( $namepart[1], '*. ' );
$check_domain = substr( $domain, -strlen( $cert_domain ) );
$res = ($cert_domain == $check_domain);
}
}
return $res;
}
if(!$res && strpos($cert['extensions']['subjectAltName']??'',"DNS:$domain") !== false) {return true;}
(它无法处理altName为通配符的情况) - the_nuts这里是我在github的某个地方找到的另一种解决方案(无法再次找到存储库...)
这是一种类似于接受答案的方法,但使用fsockopen测试我们是否可以在443端口上建立SSL连接。如果连接被拒绝,则该域名没有SSL证书。
function has_ssl( $domain ) {
$ssl_check = @fsockopen( 'ssl://' . $domain, 443, $errno, $errstr, 30 );
$res = !! $ssl_check;
if ( $ssl_check ) { fclose( $ssl_check ); }
return $res;
}
// Test it:
print_r( has_ssl('google.com') );
function has_ssl( $domain ) { return @fsockopen( 'ssl://' . $domain, 443, $errno, $errstr, 30 ); }
? - Mattfclose()
行不是OP要求的一部分,因为它不会对正确的函数响应产生贡献。但我认为关闭远程套接字也是一个好习惯,以确保所有内容都被清理干净 :) - Philipp但您可以使用此方法,该方法使用API:https://github.com/spatie/ssl-certificate
https://www.example.com
。 - deceze