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 相关文章推荐
让你同时上传 1000 个文件 (二)
Oct 09 PHP
PHP 字符串操作入门教程
Dec 06 PHP
PHP垃圾回收机制简单说明
Jul 22 PHP
php 错误处理经验分享
Oct 11 PHP
PHP使用GIFEncoder类处理gif图片实例
Jul 01 PHP
discuz目录文件资料汇总
Dec 30 PHP
php实现递归与无限分类的方法
Feb 16 PHP
使用phpstorm和xdebug实现远程调试的方法
Dec 29 PHP
调用WordPress函数统计文章访问量及PHP原生计数器的实现
Mar 21 PHP
PHP对XML内容进行修改和删除实例代码
Oct 26 PHP
浅谈PHP定义命令空间的几个注意点(推荐)
Oct 29 PHP
PHP PDOStatement::nextRowset讲解
Feb 01 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
ionCube 一款类似zend的PHP加密/解密工具
2010/07/25 PHP
PHP 图片文件上传实现代码
2010/12/29 PHP
php XPath对XML文件查找及修改实现代码
2011/07/27 PHP
探讨:parse url解析URL,返回其组成部分
2013/06/14 PHP
php实例分享之通过递归实现删除目录下的所有文件详解
2014/05/15 PHP
php中chdir()函数用法实例
2014/11/13 PHP
微信支付开发维权通知实例
2016/07/12 PHP
PHP微信分享开发详解
2017/01/14 PHP
PHP 7.4中使用预加载的方法详解
2019/07/08 PHP
TP3.2.3框架使用CKeditor编辑器在页面中上传图片的方法分析
2019/12/31 PHP
让人蛋疼的JavaScript语法特性
2014/09/30 Javascript
js+canvas绘制矩形的方法
2016/01/28 Javascript
JQuery 获取多个select标签option的text内容(实例)
2017/09/07 jQuery
微信、QQ、微博、Safari中使用js唤起App
2018/01/24 Javascript
在vue组件中使用axios的方法
2018/03/16 Javascript
浅谈Node.js 中间件模式
2018/06/12 Javascript
微信小程序项目实践之验证码倒计时功能
2018/07/18 Javascript
TypeScript中使用getElementXXX()的示例代码
2019/09/12 Javascript
javascript实现贪吃蛇小练习
2020/07/05 Javascript
浅谈Python中copy()方法的使用
2015/05/21 Python
Python实现快速排序算法及去重的快速排序的简单示例
2016/06/26 Python
TensorFlow平台下Python实现神经网络
2018/03/10 Python
Python中Numpy mat的使用详解
2019/05/24 Python
python3.8 微信发送服务器监控报警消息代码实现
2019/11/05 Python
使用TensorFlow-Slim进行图像分类的实现
2019/12/31 Python
Python爬虫谷歌Chrome F12抓包过程原理解析
2020/06/04 Python
pyspark对Mysql数据库进行读写的实现
2020/12/30 Python
美国最大的宠物用品零售商:PetSmart
2016/11/14 全球购物
美国高端寝具品牌:Coyuchi
2017/02/08 全球购物
jQuery treeview树形结构应用
2021/03/24 jQuery
理工类毕业自我鉴定
2014/02/20 职场文书
幼儿教师暑期培训方案
2014/08/27 职场文书
2015年全国爱眼日活动小结
2015/02/27 职场文书
婚庆公司开业主持词
2015/06/30 职场文书
2015年国庆节演讲稿范文
2015/07/30 职场文书
pytorch中的numel函数用法说明
2021/05/13 Python