首頁  >  文章  >  後端開發  >  php使用Socket取得網站的SSL憑證與公鑰範例程式碼

php使用Socket取得網站的SSL憑證與公鑰範例程式碼

怪我咯
怪我咯原創
2017-07-13 09:18:221370瀏覽

socket(電腦專業術語)

網路上的兩個程式透過雙向的通訊連線實現資料的交換,這個連線的一端稱為一個socket。

建立網路通訊連線至少要一對埠號(socket)。 socket本質是程式設計介面(API),對TCP/IP的封裝,TCP/IP也要提供可供程式設計師做網路開發所用的接口,這就是Socket程式介面;HTTP是轎車,提供了封裝或顯示數據的具體形式;Socket是發動機,提供了網路通訊的能力。

Socket的英文原義是「孔」或「插座」。作為BSD UNIX的進程通訊機制,取後一種意思。通常也稱為"套接字",用於描述IP位址和端口,是一個通訊鏈的句柄,可以用來實現不同虛擬機或不同電腦之間的通訊。在Internet上的主機一般運行了多個服務軟體,同時提供幾種服務。每種服務都開啟一個Socket,並綁定到一個連接埠上,不同的連接埠對應於不同的服務。 Socket正如其英文原意那樣,像一個多孔插座。一台主機猶如佈滿各種插座的房間,每個插座有一個編號,有的插座提供220伏交流電, 有的提供110伏交流電,有的則提供有線電視節目。 客戶軟體將插頭插到不同編號的插座,就可以得到不同的服務。

這篇文章主要為大家介紹了PHP利用Socket取得網站的SSL憑證與公鑰的相關資料,文中給了詳細的範例程式碼供大家參考學習,對大家有一定的參考學習價值,需要的朋友們下面來一起看看吧。

透過 php curl 請求網頁並不能取得到憑證訊息,此時需要使用 ssl socket 取得憑證內容。下面來一起看看詳細的介紹:

範例程式碼:

// 创建 stream context
$context = stream_context_create([
 'ssl' => [
  'capture_peer_cert' => true,
  'capture_peer_cert_chain' => true,
 ],
]);
 
$resource = stream_socket_client("ssl://$domain:$port", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
$cert = stream_context_get_params($resource);
 
$ssl = $cert['options']['ssl'];
$resource = $ssl['peer_certificate'];
 
// 网站证书中只有公钥,通过 openssl_pkey_get_details 导出公钥
 
$ret = [
 'crt' => '',
 'pub' => '',
];
 
$pkey = openssl_pkey_get_public($resource);
$ret['pub'] = openssl_pkey_get_details($pkey)['key'];
 
openssl_x509_export($resource, $pem);
$ret['crt'] = $pem;
 
foreach ($ssl['peer_certificate_chain'] as $resource)
{
 openssl_x509_export($resource, $pem);
 $ret['crt'] .= "\n" . $pem;
}
 
// 保存 $ret['crt'] 为 domain.crt
// 保存 $ret['pub'] 为 domain.pub
 
return $ret;

驗證憑證中的公鑰A是否正確,透過私鑰匯出公鑰B,比較兩者發現一致。

$domain = 'blog.zhengxianjun.com';
$port = '443';
// ...
$pub_a = $ret['pub'];
 
$private_key_path = '/conf/ssl/blog.zhengxianjun.com.key';
 
// 证书没有设置密码,$passphrase 为空字符串
$pkey = openssl_pkey_get_private(file_get_content($private_key_path), $passphrase = '');
$pub_b = openssl_pkey_get_details($pkey)['key'];
 
// 两者一致
var_dump($pub_a === $pub_b);

函數 stream_socket_client 還有一個用途是當知道伺服器 IP 時,可以取得伺服器可能可以使用的網域名稱。

$resource = stream_socket_client("ssl://$ip:$port", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
$cert = stream_context_get_params($resource);
 
// 解析 X.509 格式证书
$info = openssl_x509_parse($cert['options']['ssl']['peer_certificate']);
 
// 获取证书中的可信域名列表
$domain = str_replace('DNS:', '', $info['extensions']['subjectAltName']);

以上可以看到取得網站憑證並不能取得私鑰。

在一些使用 CDN 的站點,如果使用了 HTTPS 同時又希望使用自有域名,是否需要將自己的私鑰提供給 CDN 廠商呢?實際上憑證路徑與使用者名稱(支援 https 的網域名稱)並不需要一致。

也就是使用自有網域並進行 CDN 加速時不需要使用自有的 ssl 證書,只需將自己的 CDN 網域加到廠商證書的網域清單即可。

以上是php使用Socket取得網站的SSL憑證與公鑰範例程式碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn