在每个 Windows 对话框中都能看到 PIV 卡证书,VPN 登录仍可能失败,因为可见性和可用性是不同的属性。证书是公开对象;登录需要由卡按其自身访问规则执行的私钥操作。在这两个事实之间有四道阶段,它们以四种不同方式失败:配置文件选择、证书选择、本地签名和服务端验证。按顺序走过它们,就能把笼统的握手错误变成针对下一环节负责人的具体问题。

从配置文件和 EAP 方法开始

打开连接属性,读出配置文件实际使用的 EAP 方法,再读出该方法被配置为选择哪张证书。许多部署同时有基于证书的外层方法和内层方法,而连接级别配置的证书并不自动等于在 EAP-TLS 内部出示的那一张。如果配置文件按颁发者或按主题筛选器选择证书,该筛选器是从 Windows 在相应存储中能看到的内容里挑选,而不是从卡上碰巧拥有的内容里挑选。匹配不到任何内容的筛选器会退回到提示或静默失败,取决于配置文件的配置,因此在任何改动之前记录所选指纹是值得的。

还要确定连接是以已登录用户身份运行,还是以计算机身份运行。仅这一点就决定了哪些证书存储落在范围内,以及哪个安全上下文执行签名。

确认选择了哪张证书

把 Windows 选择的指纹与要求逐项比对:客户端身份验证用途、终止于受信任根的链、身份验证服务器策略能够映射的身份,以及覆盖尝试实际时刻的有效期。这些是彼此独立的检查,最后一项带来的意外比人们预想的多,尤其是滚动签发的证书,以及仍指向昨天选择的缓存配置文件。

用户与计算机上下文是检查的另一半。用户个人存储中的证书对以计算机身份运行的服务不可见,而计算机证书不会由用户模式 EAP 交换出示,除非配置文件这样规定。把证书重新导入错误的存储,会得到可见的证书和不可见的登录凭据。要读配置文件里的存储路径,而不是碰巧打开的那个对话框中的路径。

在不猜 PIN 的前提下测试密钥操作

选择确定之后,问题在于卡是否会执行签名。Windows 需要受支持的卡提供程序或微型驱动程序才能触达私钥,而设备会对该操作施加自己的 PIN 和存在规则。配置为每次签名都要求触摸的卡,与为一次会话缓存验证结果的卡行为不同,两者都是合法配置,只是改变了提示出现的时机。这一差异解释了一次登录在新插入时成功、而在从睡眠恢复后失败,却没有任何证书出错。

certutil.exe -scinfo
certutil.exe -store -user My
Get-WinEvent -LogName Application -MaxEvents 40 | Where-Object ProviderName -like '*Ras*'

第一条命令清点卡并报告读卡器与提供程序状态,这在 Microsoft 的智能卡调试指南 中有记录。第二条列出用户上下文实际能看到的内容。两者都不能证明身份验证成功;它们都只是缩小了它停在哪一步。

不要猜 PIN。卡会强制重试次数限制,几次乐观的尝试就把权限问题变成需要管理员恢复的被锁凭据。如果本地签名失败,记录提供程序状态和卡状态,而不是尝试各种变体。用同一配置文件、同一证书和已知良好的读卡器路径重复一次尝试,然后比较两条记录;同时改动多个变量只会得到故事,而不是结果。

读取握手的两端

签名完成仍不等于准入。身份验证服务器必须接受该链、检查吊销、按其当前规则映射身份并授权请求;客户端则必须按配置文件要求验证服务器证书。由服务器生成的 TLS 警报在客户端日志中看起来与本地生成的完全相同,因此发出方比警报文本更重要。

收集时间戳对齐的 Windows 事件和服务端事件,然后判断哪一侧产生了第一次失败。RFC 5216 描述了 EAP-TLS 中的持有证明步骤,而笼统的握手警报本身并不指明本地密钥原因。正是时间戳比对把两份日志变成一条序列。

在报告中把边界写清

把报告写成四个阶段,各给一个结论:哪个配置文件与上下文在运行、Windows 选择了哪张证书、卡是否完成签名,以及服务器作出了什么决定。这种结构让下一步显而易见,并阻止那种为了越过无人识别的阶段而关闭验证的常见修法。

作为临时对比,软件证书是合法的管理员测试,但它改变了凭据与保证模型,因此属于已批准的变更,而不是生产环境中的静默变通。同样的纪律适用于 PIN 尝试,也适用于在失败阶段尚未查清之前重新签发凭据。一张同样失败的替换卡,是问题从来不在卡上的昂贵证据。

相关文章