V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
caola
V2EX  ›  PHP

PHP 怎样才能验证 ssl/tls 证书的有效性

  •  
  •   caola · 2020-08-14 18:08:28 +08:00 · 4250 次点击
    这是一个创建于 1560 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在本地有公钥和私钥(客户端上传的),但不清楚这证书是否 可信证书机构签发并且是有效的

    php 可以通过 curl 和 stream_socket_client 建立握手时验证(这是架设好的服务器连接上)

    想问下大家有没有什么方法,php 直接对证书文件进行真实性的验证,或者有什么插件和其他的方法。

    10 条回复    2020-08-17 11:15:42 +08:00
    julyclyde
        1
    julyclyde  
       2020-08-14 18:20:02 +08:00
    调 openssl
    x509 verify
    caola
        2
    caola  
    OP
       2020-08-14 20:57:29 +08:00
    @julyclyde PHP 的 openssl_x509_verify() 只是验证,公钥和私钥是否对的(包括自签证书),无法判断出是否可信机构签发并且是有效的
    除了调用外部的其他程序验证,我真想不出还有什么方法
    foMM
        3
    foMM  
       2020-08-14 23:21:43 +08:00 via Android
    解构证书文件,获取 ocsp 地址,然后查 ocsp
    julyclyde
        4
    julyclyde  
       2020-08-14 23:45:10 +08:00 via iPad
    @caola 我的意思是调用外部命令 openssl 不是 php 的 openssl 扩展
    不过真是没想到 php 的 openssl 扩展居然不支持从 CA 验证证书
    xiangyuecn
        5
    xiangyuecn  
       2020-08-15 00:02:52 +08:00
    按道理就是 用你的可信根证书列表(系统自带?)里面的根证书对 某个证书进行校验就 ok 了,签名正确就 ok,简单点不管吊销过期什么的。

    然后就出来了一连串的:
    根证书签发的中间证书的验证
    中间证书签发的中间证书验证
    ....
    中间证书签发的证书验证
    验证完。

    怎么进行验证就要一个礼拜来学了。如果你系统里面+证书里面都没有某个中间证书,还会出现证书链丢失的问题,还要用户上传证书链😂 可怕不可怕
    jim9606
        6
    jim9606  
       2020-08-15 07:28:19 +08:00
    具体验证逻辑还挺复杂的,尽量用 openssl CLI 来验证吧,也就是 @julyclyde 说的方法。信任根 CA 建议自己打包一个列表,不要直接用系统的证书存储。

    一路下来验证要点还蛮多的,除了要构成链条,还要检查算法强度、证书目的、使用者名称、有效期等。
    jinliming2
        7
    jinliming2  
       2020-08-15 11:40:42 +08:00   ❤️ 1
    curl 、openssl 之类 linux 下的应用都是使用 ca-certificates 这个包提供的 CA 证书列表来信任的。
    所以你可以直接下载这个包( ubuntu 仓库镜像下载或者直接 apt 下载 deb 包),解压,就可以得到所有可信 CA 的列表了。
    你可以再根据需要删除或增加部分 CA 证书。
    然后用这个 CA 证书列表去验证你要验证的证书是否是可信的。
    caola
        8
    caola  
    OP
       2020-08-16 13:41:20 +08:00
    @foMM @jim9606 @jinliming2 @julyclyde @xiangyuecn 感谢各位的回答,我目前找到两个解决方法
    第一:使用 phpseclib 这个包勉强能用(不完美)
    第二:按 php 官方文档 openssl_verify() 函数下面[mikey at badpenguins dot com] 给出的链接(代码)来修改一下,但这个必须要知道所有的证书链才能一级一级的验证(完整证书链的证书才能)

    上面的两个方法都不能验证吊销和日期,都要手动拿所有的信任根 CA 列表去验证,
    其实吊销就不太重要了,日期可以直接读取出来手动判断,
    虽然不完美,但是能用就行了
    julyclyde
        9
    julyclyde  
       2020-08-17 11:15:00 +08:00
    @jim9606 为什么不要使用系统的证书存储啊?
    julyclyde
        10
    julyclyde  
       2020-08-17 11:15:42 +08:00
    @xiangyuecn 服务器端一般出示证书链,全链或者缺一层根的链
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1053 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 19:30 · PVG 03:30 · LAX 11:30 · JFK 14:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.