证书在 Windows 中可见,OpenVPN 却用不了它的私钥
Windows 证书存储里的证书不等于可用的身份。检查客户端的存储选择器、私钥,以及进程运行所用的账户。
证书在 Windows 证书查看器里看得见,客户端却仍然用不了它。看得见证书只能证明某个存储里存在一个公开对象。它不能证明连接进程能找到对应的私钥,也不能证明该进程有权使用这把私钥。
三个对象必须对齐。所选证书、它背后的私钥,以及客户端运行所用的账户,是三件彼此独立的东西,每一件都可能单独出问题。
三个对象,三种答案
Windows 上的社区版 OpenVPN 提供了一种 CryptoAPI 存储选择器 cryptoapicert,它接收指纹。这个值必须指向你真正想用的那张证书,而不是名字相近的另一张。其他基于 OpenVPN 的应用可能采用完全不同的导入模型,所以这个选择器只对记录了它的那个构建版本构成证据。在向下排查任何环节之前,先确认你的客户端实现了这一机制。
如果该构建不支持这个选择器,解决办法是换一种配置文件格式,而不是换一张证书。
选择器是否解析到正确的身份
公开证书可以在没有私钥的情况下被导入。证书查看器两种情况都会显示它,这正是此故障看起来像客户端无视一张明明存在的证书的原因。要检查私钥关联,而不只是条目是否存在。
续期后的证书会带来第二个陷阱。两条条目可能都留在存储里,而配置文件仍指向旧的指纹,客户端于是继续选中你本想弃用的那个身份。
在看权限之前,先确认选择器解析到哪个身份。指纹错误与私钥缺失是同一种失败。
这个账户能否使用私钥
私钥访问按账户计算。服务、计划任务和交互式桌面会话可能对存储有不同的视图,也有不同的私钥使用权限。证书在你自己的会话里可见,并不说明服务账户如何。
由硬件承载的私钥可能需要它自己的提供程序和一个确认步骤。无法弹出提示的服务,不会因为把私钥导出成普通文件而得救。
先读本地报错,再动手改动。选择失败、签名失败和服务端拒绝是三种不同的结果。只有前两种是本地问题。第三种意味着私钥工作正常,是服务端否定了这张证书。
本地能用不等于服务端接受
本地成功不等于授权。客户端用自己的私钥签完名之后,服务端仍会评估签发者、有效期、角色以及它自己的访问策略。来自同一 CA 的另一张证书不会自动带着同样的 VPN 权限。
服务端需要的是信任链,而不是客户端私钥的副本。把私钥发给服务端,从来不是验证问题的修复办法。
按顺序处理故障
保留准确的报错原文。缺少私钥权限不应变成更换 CA,服务端拒绝也不应变成修复存储。每种情况都有自己的证据。
按故障出现的顺序处理:选择器、私钥、账户,最后是服务端策略。社区版客户端参考记录了你所运行版本对应的 Windows 存储选择器。