最近遇到一个挺典型的问题:用户反馈打开我们小程序时,其中一台安卓手机弹出了安全证书警告,提示 xxx.com 的证书存在问题,可以选择"继续"访问;而另一台安卓手机打开同一个页面,却什么都不弹,直接正常访问。

第一反应很容易归结为"手机太旧了"。但仔细想想,这个结论对解决问题没有任何帮助------用户不可能因为一个弹窗就去换手机。问题必须由我们服务端来解决。
可以使用一些工具检查证书链完整性(如果不知道就问AI), 把证书信息拉出来,完整看了一遍证书链,问题的根源就清楚了。
问题
证书本身没问题,问题出在"链"上,我们的证书是 *.aswulian.com,由 WoTrus RSA DV SSL CA 2 签发。往下看证书链,路径是这样的:
txt
*.aswulian.com
→ WoTrus RSA DV SSL CA 2
→ Sectigo Public Server Authentication Root R46
→ USERTrust RSA Certification Authority
→ AAA Certificate Services
这条链从表面看是完整的,一路连到了一个非常老的根 AAA Certificate Services。但问题恰恰出在中间那一环:Sectigo Public Server Authentication Root R46。
Sectigo 在 2025 年启用了新的根证书体系,R46 就是其中之一。较新的 Android、iOS、Windows 系统信任库里已经预置了这个根,所以新手机验证时一路畅通,什么都不弹。但很多旧版安卓系统的内置信任库里根本没有 R46,手机走到这一步就"不认识"了,信任链断裂,于是弹出安全警告。
这就是为什么同一张证书,一部手机弹、另一部不弹------不是证书无效,而是旧手机的信任库不认识链上的新根。
真正的问题:服务器没把该发的证书发出去
理论上,Sectigo 为这个新根提供了交叉签名证书,能把 R46 链接回旧设备普遍信任的 USERTrust 根,从而兼容旧设备。我们的证书包里也确实包含这条路径。
但实际部署时,很多服务器软件(尤其是 Windows/IIS)会优先选择"最短路径"。它看到 R46 本身是个根,就直接把链断在那里,不把交叉签名证书发给客户端。结果就是:新手机认识 R46,没事;旧手机不认识 R46,信任链断了,弹窗出现。
换句话说,证书包里本来有那一页"介绍信",但服务器没把它发给手机。
如何修
解决办法不在用户手机端,而在服务端配置。按部署环境分几种情况:
Windows / IIS:
Sectigo 官方提供了修复工具,下载并运行对应的 .reg 文件,把自签名的 R46 根证书标记为"不信任",迫使 Windows 使用部署的交叉签名链。
Nginx / Apache 或云负载均衡:
检查配置的证书链文件(fullchain.pem 或 ca-bundle.crt),确保里面不仅包含 WoTrus RSA DV SSL CA 2,还必须包含 Sectigo 提供的交叉签名根证书。顺序应为:域名证书 → WoTrus 中间证书 → 交叉签名 R46 证书 → USERTrust 根证书。配置好后用 openssl s_client 或 MySSL 再测一次,确认服务器实际发出的链里包含了 USERTrust 那一环。
云服务(如 Azure Front Door 等):
有案例显示,即使源站放了完整的交叉签名链,云服务也可能只发短链。需要检查云服务商是否有强制发送完整链的配置,或者在源站层面强制指定证书链。
小结
这次问题的教训是:证书"有效"不等于"兼容"。 证书链的完整性、根证书的新旧、服务器实际下发的链内容,任何一环出问题,都可能导致部分设备验证失败。
遇到"一部手机弹、一部不弹"的情况,先别急着怪手机旧。把证书链拉出来完整看一遍,用 MySSL 或 SSL Labs 测一下服务器实际下发的链包含了几张证书,往往就能定位到问题。补上该发的那一页证书,用户的弹窗自然就消失了------不需要任何人换手机。