我正在构建一个脚本,用于检查网站是否使用SSL。例如,我们使用“http://www.google.com/”将其重定向到“https://www.google.com/”。我该怎么检查?我正在使用以下cURL代码来获取网站的标题。
<?php
$url = 'https://www.google.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); // set url
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6"); // set browser/user agent
curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header'); // get header
curl_exec($ch);
function read_header($ch, $string) {
print "Received header: $string";
return strlen($string);
}
?>
输出:
HTTP/1.1 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Location: https://www.google.co.in/?gfe_rd=cr&ei=YEAkV7SEFrTv8wexyy0
Content-Length: 259
Date: Sat, 30 Apr 2016 05:19:28 GMT
Alternate-Protocol: 443:quic
Alt-Svc: quic=":443"; ma=2592000; v="33,32,31,30,29,28,27,26,25"
答案 0 :(得分:4)
PHP - cURL
我认为使用cURL是一种矫枉过正,但无论如何你都去了。
<?php
function ignoreHeader( $curl, $headerStr ) {
return strlen( $headerStr );
}
$curl = curl_init( "https://example.com/" );
curl_setopt( $curl, CURLOPT_NOBODY, TRUE );
curl_setopt( $curl, CURL_HEADERFUNCTION, 'ignoreHeader' );
curl_exec( $curl );
$result = false;
if ( curl_errno($curl) == 0 ) {
$info = curl_getinfo( $curl );
if ( $info['http_code'] == 200 ) {
$result = true;
}
}
?>
PHP - 没有cURL
如果您想检查网站是否有SSL证书。您只需打开一个流并检查SSL证书参数。
<?php
// Create a stream context
$stream = stream_context_create ( array( "ssl" => array( "capture_peer_cert" => true ) ) );
// Bind the resource 'https://www.example.com' to $stream
$read = fopen( "https://www.example.com", "rb", false, $stream );
// Get stream parameters
$params = stream_context_get_params( $read );
// Check that SSL certificate is not null
// $cert should be for example "resource(4) of type (OpenSSL X.509)"
$cert = $params["options"]["ssl"]["peer_certificate"];
$result = ( !is_null( $cert ) ) ? true : false;
?>
如果要检查主机是否接受443端口上的连接,可以使用fsockopen
启动与主机的套接字连接。
<?php
// Set host and port.
$host = 'example.com';
$port = 443;
// Initiate a socket connection with 'example.com' and check the result.
$fp = fsockopen(ssl://{$host}, $port, $errno, $errstr, 30);
$result = ( !is_null( $fp ) ) ? true : false;
?>
答案 1 :(得分:2)
为了满足要求&#34; 此网站使用SSL &#34;我们需要先了解&#34; 使用SSL &#34;实际上意味着。
在HTTP客户端的上下文中,它通常意味着服务器至少在HTTP请求的标准SSL端口(端口443 )上进行侦听。所以一个好的第一个检查可能是简单地尝试启动到该端口上的远程服务器的TCP连接。如果远程主机接受连接,我们至少知道是否尝试,以及我们是否知道它没有在标准SSL端口上侦听。
因为这个cURL有点太高了。因此,我们可以尝试在指定端口上使用fsockopen
which makes it possible to simply open this internet connection并获取足够的信息以了解我们需要什么。远程主机是否甚至在此端口上侦听或接受连接?
function connect($host, $port, $timeOut = 5) {
$fp = fsockopen($host, $port, $errno, $errstr, $timeOut);
if (!$fp) {
printf("It looks like the host '%s' does not accept connections on port %d - error #%d [%s]\n", $host, $port, $errno, $errstr);
return true;
} else {
fclose($fp); // we know it's listening
printf("It looks like the host '%s' does accept connections on port %d\n", $host, $port);
return false;
}
}
$host = "www.google.com";
$port = 443;
connect($host, $port);
这实际上并不能确认远程主机是否实际上使用SSL进行通信,但它至少会告诉您是否值得尝试与标准服务器通信SSL端口。这是一种廉价的方式,因为我们不会先尝试通过SSL发送请求。如果您想尝试通过https进一步发送请求并通过curl确认响应成功,那么您当然也可以这样做。
虽然根据您的问题,我认为您认为仅仅因为服务器通过HTTP发送位置标头,这就会以某种方式结束网站使用SSL。这不是真的。远程主机可以接受两个端口上的流量,而且经常会这样做。远程主机也可能不会通过标准HTTP端口将所有流量重定向到SSL端口(,即尝试从http 重定向到https)。实际上,远程主机可能根本不在端口80上侦听。它可能依赖于HSTS or HTTP Strict Transport Security之类的东西。
在所有情况下,确认远程主机通过HTTP使用SSL传输的唯一方法实际上是成功建立连接。通过curl的https请求成功产生响应的事实将在某种程度上得出结论,假设您正在通过所有正确的SSL通道,例如验证对等证书和远程身份。