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入门之连接mysql数据库的一个类
Apr 21 PHP
基于initPHP的框架介绍
Apr 18 PHP
PHP限制页面只能在微信自带浏览器访问的代码
Jan 15 PHP
ThinkPHP应用模式扩展详解
Jul 16 PHP
非常实用的PHP常用函数汇总
Dec 17 PHP
PHP跨平台获取服务器IP地址自定义函数分享
Dec 29 PHP
CentOS安装php v8js教程
Feb 26 PHP
PHP多线程之内部多线程实例分析
Mar 09 PHP
PHP常见漏洞攻击分析
Feb 21 PHP
php函数传值的引用传递注意事项分析
Jun 25 PHP
php opendir()列出目录下所有文件的实例代码
Oct 02 PHP
tp5.1 实现setInc字段自动加1
Oct 18 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
用session做客户验证时的注意事项
2006/10/09 PHP
PHP微信开发之微信录音临时转永久存储
2018/01/26 PHP
JS的IE和Firefox兼容性集锦
2006/12/11 Javascript
pjblog修改技巧汇总
2007/03/12 Javascript
js GridView 实现自动计算操作代码
2009/03/25 Javascript
JS(JQuery)操作Array的相关方法介绍
2014/02/11 Javascript
如何实现chrome浏览器关闭页面时弹出“确定要离开此面吗?”
2015/03/05 Javascript
JavaScript实现表格点击排序的方法
2015/05/11 Javascript
阿里巴巴技术文章分享 Javascript继承机制的实现
2016/01/14 Javascript
jQuery实现三级菜单的代码
2016/05/09 Javascript
javascript中获取元素标签中间的内容的实现方法
2016/10/08 Javascript
js实现图片懒加载效果
2017/07/17 Javascript
js es6系列教程 - 基于new.target属性与es5改造es6的类语法
2017/09/02 Javascript
JavaScript设计模式之原型模式分析【ES5与ES6】
2018/07/26 Javascript
[04:10]2016国际邀请赛中国区预选赛第二日TOP10精彩集锦
2016/06/28 DOTA
PyQt5 窗口切换与自定义对话框的实例
2019/06/20 Python
2020最新pycharm汉化安装(python工程狮亲测有效)
2020/04/26 Python
Python中如何添加自定义模块
2020/06/09 Python
python的数学算法函数及公式用法
2020/11/18 Python
Python之京东商品秒杀的实现示例
2021/01/06 Python
英国书籍、CD、DVD和游戏的第一道德零售商:Awesome Books
2020/02/22 全球购物
C#如何调用Windows程序打开一个文档
2014/12/26 面试题
写好自荐信的几个要点
2013/12/26 职场文书
七年级音乐教学反思
2014/01/26 职场文书
全国道德模范事迹
2014/02/01 职场文书
上班打牌检讨书
2014/02/07 职场文书
农民工工资承诺书范文
2014/03/31 职场文书
党的群众路线教育实践活动调研报告
2014/11/03 职场文书
酒店辞职书怎么写
2015/02/26 职场文书
排球赛新闻稿
2015/07/17 职场文书
教师理论学习心得体会
2016/01/21 职场文书
2016年优秀少先队辅导员事迹材料
2016/02/26 职场文书
发言稿之优秀教师篇
2019/09/26 职场文书
MySQL优化常用的19种有效方法(推荐!)
2022/03/17 MySQL
Python实现双向链表基本操作
2022/05/25 Python
Win10加载疑难解答时出错发生意外错误的解决方法
2022/07/07 数码科技