PHP利用Socket获取网站的SSL证书与公钥


Posted in PHP onJune 18, 2017

通过 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 相关文章推荐
特转载一高手总结PHP学习资源和链接.
Dec 05 PHP
PHP 采集获取指定网址的内容
Jan 05 PHP
PHP垃圾回收机制简单说明
Jul 22 PHP
深入array multisort排序原理的详解
Jun 18 PHP
php异常处理使用示例
Feb 25 PHP
php中字符集转换iconv函数使用总结
Oct 11 PHP
php中常见的sql攻击正则表达式汇总
Nov 06 PHP
PHP5.4起内置web服务器使用方法
Aug 09 PHP
php利用gd库为图片添加水印
Nov 09 PHP
PHP laravel中的多对多关系实例详解
Jun 07 PHP
PHP实现的简单在线计算器功能示例
Aug 02 PHP
Yii2.0 RESTful API 基础配置教程详解
Dec 26 PHP
php实现批量上传数据到数据库(.csv格式)的案例
Jun 18 #PHP
PHP更安全的密码加密机制Bcrypt详解
Jun 18 #PHP
Laravel中log无法写入问题的解决
Jun 17 #PHP
php下载远程大文件(获取远程文件大小)的实例
Jun 17 #PHP
浅谈ThinkPHP5.0版本和ThinkPHP3.2版本的区别
Jun 17 #PHP
PHP 7安装调试工具Xdebug扩展的方法教程
Jun 17 #PHP
thinkphp查询,3.X 5.0方法(亲试可行)
Jun 17 #PHP
You might like
PHP抽象类 介绍
2012/06/13 PHP
ThinkPHP实例化模型的四种方法概述
2014/08/22 PHP
了解PHP的返回引用和局部静态变量
2015/06/04 PHP
py文件转exe时包含paramiko模块出错解决方法
2016/08/12 PHP
轻松掌握php设计模式之访问者模式
2016/09/23 PHP
PHP使用观察者模式处理异常信息的方法详解
2019/09/24 PHP
页面中body onload 和 window.onload 冲突的问题的解决
2009/07/01 Javascript
javascript 数据类型转换(parseInt,parseFloat)
2010/07/20 Javascript
js模拟点击以提交表单为例兼容主流浏览器
2013/11/29 Javascript
js读取csv文件并使用json显示出来
2015/01/09 Javascript
jQuery背景插件backstretch使用指南
2015/04/21 Javascript
Bootstrap打造一个左侧折叠菜单的系统模板(二)
2016/05/17 Javascript
nodejs入门教程一:概念与用法简介
2017/04/24 NodeJs
vue-router命名路由和编程式路由传参讲解
2019/01/19 Javascript
微信小程序自定义导航栏(模板化)
2019/11/15 Javascript
[01:58]最残酷竞争 2016国际邀请赛中国区预选赛积分循环赛回顾
2016/06/28 DOTA
python异步任务队列示例
2014/04/01 Python
python音频处理用到的操作的示例代码
2017/10/27 Python
在Python中使用MySQL--PyMySQL的基本使用方法
2019/11/19 Python
Python二维数组实现求出3*3矩阵对角线元素的和示例
2019/11/29 Python
Python高并发解决方案实现过程详解
2020/07/31 Python
如何解决pycharm调试报错的问题
2020/08/06 Python
详解python模块pychartdir安装及导入问题
2020/10/22 Python
Python批量修改xml的坐标值全部转为整数的实例代码
2020/11/26 Python
Python中过滤字符串列表的方法
2020/12/22 Python
CSS3使用多列制作瀑布流
2016/05/10 HTML / CSS
HTML5 FormData 方法介绍以及实现文件上传示例
2017/09/12 HTML / CSS
abstract 可以和 virtual 一起使用吗?可以和 override 一起使用吗?
2012/10/15 面试题
建房协议书
2014/04/11 职场文书
经典团队口号大全
2014/06/21 职场文书
大专应届毕业生求职信
2014/07/15 职场文书
情人节活动总结范文
2015/02/05 职场文书
辩论赛新闻稿
2015/07/17 职场文书
2019年消防宣传标语集锦
2019/11/21 职场文书
详解NodeJS模块化
2021/06/15 NodeJs
mybatis3中@SelectProvider传递参数方式
2021/08/04 Java/Android