网站证书过期打不开?我扒了自家网站的证书链才搞懂,手机里那张"用户证书"就是家门钥匙

上个月写那篇https抓包的时候,我顺嘴报了一嘴自家小站的证书是Let's Encrypt签的,2026年12月23号到期。底下有人留言问了个把我问住的问题:这证书是谁发给你的?浏览器凭什么就信?我张了张嘴发现答不利索,索性把自家网站的证书链从头到尾扒了一遍——从锁标志点开的那三行字,一路扒到手机系统里那份三百多个机构的名单。扒完才明白,平时见的「证书无效」「不安全」提示,还有手机上那个藏得很深的「安装证书」按钮,背后全是同一套规矩。
锁点开的那三行字,先看懂再说
随便开一个https网站,点地址栏那把小锁,再点「证书」,会弹出一个窗口。别被里面一堆英文吓住,真正值钱的就三行:颁发给谁、颁发者是谁、有效期到哪天。
拿我自家小站实操。在电脑上敲一行命令,把服务器递过来的证书原样接下来:
openssl s_client -connect www.shunot.com:443 -servername www.shunot.com
翻出里面那张证书,三行关键信息是这样的:颁发给shunot.com;颁发者Let's Encrypt的一个叫YR1的中间机构;有效期2026年9月24号到12月23号。掐指一算正好90天,这不是巧,是Let's Encrypt定死的规矩——它家证书一律90天一换,逼着站长配自动续期,别把一张证书用到大半年忘了换。商业证书动辄一年起步,图省事的个人站长反而容易在到期那天翻车:早上网站还好好的,中午突然满屏红字打不开,一查,证书过期了。
顺带一个冷知识:那张证书里除了shunot.com,还写着www.shunot.com——这叫SAN,一张证书管多个名字。所以带www和不带www都能正常开,不是服务器做了什么跳转魔法,是证书一开始就把两个名字都备案了。
证书链就是介绍信,一层背书一层
光看自己那张证书不过瘾,我加了个参数把整条链子全拉出来:openssl s_client -showcerts。好家伙,服务器递过来的不是一张,是三张,跟套娃一样:
| 第几张 | 写着啥 | 谁给它作证 |
| 叶子证书 | 我是shunot.com | Let's Encrypt的YR1 |
| 中间证书 | 我是YR1 | Root YR |
| 再上一级 | 我是Root YR | ISRG Root X1 |
整套东西就是介绍信制度。网站证书说「我是shunot.com,YR1可以作证」;你去找YR1,YR1掏出自己的证书说「我是YR1,Root YR作证」;再往上找,Root YR说「ISRG Root X1作证」。一路找到ISRG Root X1这里,链子到头了——它不需要再有人作证,因为它本人的名字,出厂就印在你手机和电脑里那份信任名单上。
当初我想不通一件事:既然根这么权威,为什么不直接用根给每个网站签证书,中间搞这两层干什么?后来查明白,根证书的私钥是整个机构的命根子,业界规矩是把它离线封存——锁在没有网络的机房甚至保险柜里,平时绝不下地干活。日常签字的活全交给中间证书:中间的私钥万一泄露或者要轮换,吊销重发一张就完事,根毫发无伤。要是根私钥直接暴露,那家机构签过的所有网站全体完蛋,这种事不是没发生过,荷兰一家叫DigiNotar的证书机构2011年就是因为根私钥被盗,浏览器厂商连夜把它从信任名单里整个踢了出去,公司当年就倒闭了。
浏览器验证书,就是拿着名单对暗号
那这份「信任名单」到底长什么样?我在这台电脑上数了一遍:/etc/ssl/certs目录下躺着302张证书。Windows、安卓、苹果各自维护一份类似的名单,内容大同小异——三百来个机构的名字,你认得出的可能不到五个,剩下的DigiCert、Sectigo、GlobalSign、Entrust,全是这辈子没打过交道但全世界都得信的机构。
所以每次你打开一个https网站,后台实际发生的事是这样的:服务器把三张证书一起递过来,浏览器先看叶子那张的介绍人是谁,在自己名单里翻,翻到了就验一层签名,再顺着往上找,一级一级验到根,终点必须落在那302个名字里头。链子中间断一环,或者终点不在名单上,立刻报警。整个验证几毫秒完事,你感觉不到,但这套「对暗号」每天在你手机上跑成千上万次。
这也是为什么抓包工具非要你装它的证书——后面细说,这是全文最要紧的一段。
三种报错三种病,先读错误页那行小字
证书验证失败,Chrome不会只说「出错了」,它会在错误页里写一行小字,比如NET::ERR_CERT_DATE_INVALID。这行英文就是病历本,三种常见报错对三种病:
| 报错关键词 | 病根 | 第一动作 |
| DATE_INVALID(有效期不对) | 证书真过期了,或者你手机电脑的时间不对 | 先看系统时间 |
| AUTHORITY_INVALID(颁发者不认识) | 自签证书,或者有人在中间冒充 | 想想自己在哪连的网 |
| COMMON_NAME_INVALID(名字对不上) | 证书是给A网站签的,你访问的却是B | 检查网址敲没敲错 |
DATE_INVALID最冤枉的一种:明明网站好好的,就因为你电脑主板电池扣了、时间回到1970年,浏览器一看证书的有效期「还没开始」,直接判你不过关。家里路由器断电后时间归零,那台机器上开https网站必报这个错,我之前写NTP对时那篇专门吐槽过——时间不准害的不只是定时任务,还害证书。所以遇到证书报错,先花五秒钟看看右下角日期,再决定要不要折腾别的。
AUTHORITY_INVALID要分场合。家里NAS的网页后台用自签证书,浏览器满屏红字,这属于「你知道自己在干嘛」——自家设备、自家局域网,我在WebDAV那篇里写过处理办法,红字可以继续。但要是你在网吧、酒店大堂这种公共WiFi下访问网银,跳出这个错,别点「继续访问」,扭头就走——那个场合下它意味着有人可能正站在你和真网站中间。名字对不上那种反而最轻,多数是网址敲错或者运营商页面插了一脚,跟错误码那点事是一个路数,翻我那篇状态码白话文就明白了。
手机里那张「用户证书」,就是家门钥匙
写到这,该说最要紧的事了:装证书这个动作,比大多数人以为的重得多。
2011年12306刚上线网上售票那会儿,用的自家中铁数字证书认证中心(SRCA)签的证书,SRCA不在任何一份浏览器信任名单里,于是全国几亿人买票前都干过同一件事:去12306官网下载根证书安装包,手动装进电脑。装完浏览器就不报错了。后来12306换成国际商业CA签的证书,这个安装包才退出历史。当年安全圈吵翻天的点在于:装一张根证书,等于给这个机构发了一张「可以给任何网站作证」的通行证——它签什么你信什么,上限没有。
抓包工具走的就是这条路。想在手机上抓https的包,工具会让你先装它的根证书。装完它站在你和所有网站中间:你要访问网银,它先冒充网银把你的请求解开看一遍,再用自己的证书回给你,浏览器一看证书是「名单里那位」签的,放行。你全程只觉得网速稍微慢了点。Wifi万能钥匙类工具、某些「上网行为管理」客户端、个别来路不明的抢红包外挂,要证书的时候都是一个逻辑——它要的不是证书,是你家门钥匙的复印件。
谷歌后来补了个洞:安卓7之后,用户手动装的证书只有浏览器认,微信银行这些App默认不认。所以现在想抓App的包得root或者塞进系统目录,麻烦了一大截。但浏览器那一层的偷看,这个补丁管不着。
查的方法给你:安卓「设置→安全和隐私→更多安全设置→加密与凭据→信任的凭据」,切到「用户」标签。系统标签里那三百个是出厂带的,动不了也不用动;用户标签里每多出来一张,都值得问问自己:这是我装的吗?干嘛用的?想不起来,点进去删掉,一分钟的事。iOS在「设置→通用→关于本机→证书信任设置」里看同一件事。
收尾:三步用回日常
扒完这条链子,我给自己定了三个小习惯,也不复杂。第一,遇到证书报错先读那行小字,过期的先看时间,名字不对的先查网址,别无脑点「继续访问」也别无脑关页面。第二,手机那个「用户证书」标签页,一个季度翻一次,来路不明的当场清。第三,家里有自签证书的设备——NAS、打印机管理页这类,心里记着它为什么红字,真哪天在外面看到同样的红字才分得清轻重。浏览器的锁和https那层加密、记住你登录的cookie、存密码的钥匙库是一套班子,四个部件各管一段,凑在一块才是你每天上网时的那点安全感。搞懂证书链不敢说安全水平涨多少,至少下次那把锁变红的时候,你知道该先看哪。

发表评论