首页 > 解决方案 > X509Certificate2 仅在以管理员身份添加到当前用户存储时临时工作

问题描述

在安装用于 VPN 身份验证的自签名证书时,我遇到了一个有趣的问题:VPN 会在安装后的一段时间内成功进行身份验证,但在重新启动后我会开始收到以下消息:

错误 798:找不到可用于此可扩展身份验证协议的证书

(实际上,我在调试时写了一个完整的问题,当时我不知道原因,您可以在这里找到:Some clients can only authenticate to VPN when connected as Administrator。但总结一下:重启后用户会启动收到此消息,从那时起,只能通过以管理员身份连接来建立连接[即以管理员身份运行 rasphone 或 rasdial]。)

值得注意的是,重做安装将使连接再次工作,直到下次重新启动。

最终变得重要的原因是它属于 StackOverflow 而不是另一个站点的原因是我正在通过代码安装此证书。我编写了一个程序来自动化 VPN 安装;它做了很多事情,其中​​之一是安装客户端证书以进行身份​​验证。这是证书安装代码的缩写版本:

Dim Certs As New X509Certificate2Collection()
Certs.Import(PfxFileName, Password, X509KeyStorageFlags.PersistKeySet)

Dim ClientCert, IssuerCert As X509Certificate2

If Certs(0).HasPrivateKey Then
    ClientCert = Certs(0)
    IssuerCert = Certs(1)
Else
    ClientCert = Certs(1)
    IssuerCert = Certs(0)
End If

Using Store As New X509Store(StoreName.Root, StoreLocation.LocalMachine)
    Store.Open(OpenFlags.ReadWrite)
    Store.Add(IssuerCert)
End Using

Using Store As New X509Store(StoreName.My, StoreLocation.CurrentUser)
    Store.Open(OpenFlags.ReadWrite)
    Store.Add(ClientCert)
End Using

我的 pfx 文件总是有两个证书:带有私钥的客户端证书和没有证书的根证书。根证书需要进去,cert:/LocalMachine/Root客户端证书需要进去cert:/CurrentUser/My

使用上面的代码,会导致前面提到的问题。

标签: vb.netcertificatex509certificate2

解决方案


使用消除的过程,我运行了我的自定义安装软件的每个部分,发现仅是重新安装证书(使用上面的代码)导致连接暂时重新开始工作。然后我尝试手动安装证书(通过双击 pfx 文件并使用对话框)。

我发现当我手动安装证书时,VPN连接工作稳定,但是当我通过以前的代码安装它时,它只能工作到我下次重新启动。这向我表明,我的代码正在执行的操作与对话框正在执行的操作之间肯定存在一些差异。

然后它击中了我:我的程序正在以管理员身份运行。但是用于将证书添加到 CurrentUser 存储的对话框从不提供 UAC 提示,因此它是在我的正常用户上下文下运行的。

现在,我的程序的某些部分确实需要以管理员身份运行,因此我不得不重新设计整个程序以使用两个进程(一个管理员和一个非管理员)来执行安装的不同部分。我不会在这里讨论,但是一旦我完成了所有工作,我就尝试以非管理员身份运行以下代码部分:

Using Store As New X509Store(StoreName.My, StoreLocation.CurrentUser)
    Store.Open(OpenFlags.ReadWrite)
    Store.Add(ClientCert)
End Using

它奏效了!只要我以非管理员身份将客户端证书添加到 CurrentUser 存储,VPN 连接就能够在重新启动后始终连接。

我仍然不太明白为什么以管理员身份运行代码会导致问题。证书确实出现在 中cert:/CurrentUser/My,但是一旦出现就无法使用。也许它与相关私钥的一些隐藏权限有关?这也许可以解释为什么以管理员身份连接总是有效,但不能解释为什么以非管理员身份连接一直有效,直到重新启动。


推荐阅读