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

发布时间 - 2026-01-11 01:56:15    点击率:

通过 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  # ssl证书公钥  # sslsocket  # PHP 使用openssl 扩展实现公钥加密的方法  # php 生成加密公钥加密私钥实例详解  # 实用的PHP带公钥加密类分享(每次加密结果都不一样哦)  # php校验公钥是否可用的实例方法  # 自己的  # 公钥  # 并不能  # 不需要  # 只需  # 可以看到  # 还有一个  # 可以使用  # 这篇文章  # 谢谢大家  # 提供给  # 为空  # 是否正确  # 使用了  # 有疑问  # errstr  # STREAM_CLIENT_CONNECT  # port  # errno  # pkey 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】  如何用PHP工具快速搭建高效网站?  悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音  PHP正则匹配日期和时间(时间戳转换)的实例代码  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted  阿里云高弹*务器配置方案|支持分布式架构与多节点部署  Laravel如何创建自定义Facades?(详细步骤)  Laravel如何使用查询构建器?(Query Builder高级用法)  LinuxShell函数封装方法_脚本复用设计思路【教程】  香港服务器租用费用高吗?如何避免常见误区?  iOS正则表达式验证手机号、邮箱、身份证号等  Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门  网站图片在线制作软件,怎么在图片上做链接?  Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程  焦点电影公司作品,电影焦点结局是什么?  百度输入法ai组件怎么删除 百度输入法ai组件移除工具  实现点击下箭头变上箭头来回切换的两种方法【推荐】  常州企业网站制作公司,全国继续教育网怎么登录?  Python并发异常传播_错误处理解析【教程】  浅谈Javascript中的Label语句  javascript日期怎么处理_如何格式化输出  Bootstrap CSS布局之列表  html5如何实现懒加载图片_ intersectionobserver api用法【教程】  制作企业网站建设方案,怎样建设一个公司网站?  Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】  韩国服务器如何优化跨境访问实现高效连接?  Win11怎么开启自动HDR画质_Windows11显示设置HDR选项  Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】  Python自动化办公教程_ExcelWordPDF批量处理案例  Laravel Docker环境搭建教程_Laravel Sail使用指南  北京网页设计制作网站有哪些,继续教育自动播放怎么设置?  Laravel怎么配置S3云存储驱动_Laravel集成阿里云OSS或AWS S3存储桶【教程】  WordPress 子目录安装中正确处理脚本路径的完整指南  Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲  EditPlus中的正则表达式实战(5)  Laravel如何为API编写文档_Laravel API文档生成与维护方法  详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)  Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?  php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】  百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏  如何挑选高效建站主机与优质域名?  企业网站制作这些问题要关注  如何确保FTP站点访问权限与数据传输安全?  如何在服务器上三步完成建站并提升流量?  标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?  Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】  Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】  Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】  哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】