【问题标题】:Cannot retrieve programmatically a certificate installed through mmc for a service account无法以编程方式检索通过 mmc 为服务帐户安装的证书
【发布时间】:2020-10-16 08:32:12
【问题描述】:

我正在尝试将应用程序转变为服务 (.NET)。此服务必须通过 Web 服务(FileNet P8 .NET 凭证系统)登录远程服务器。

但是,URL 是 HTTPS,因此需要证书。

我跟随 Microsoft's instructions 为 MMC 的服务帐户安装了证书。证书(自签名)安装在 Trusted Root Certification Authorities Certificate Store 中。 (免责声明:我还不太了解 MMC 是如何工作的,尤其是当更改生效时)。

证书存在于HKLM\SOFTWARE\Microsoft\Cryptography\ Services\<ServiceName>\SystemCertificates\Root\Certificates\<digitalFootprint>。

但是,这段代码没有检索到证书:

' Environment.UserName = SERVICE LOCAL (french)
LOGGER.info("Certifs for " & Environment.UserName)
Dim store As X509Certificates.X509Store =
    New X509Certificates.X509Store(X509Certificates.StoreName.Root,
                                   X509Certificates.StoreLocation.CurrentUser)
store.Open(X509Certificates.OpenFlags.ReadOnly)
For Each certificate As X509Certificates.X509Certificate2 In store.Certificates
    LOGGER.info(certificate.Issuer & ": " & 
                If(certificate.Verify, "Valid", "Invalid"))
Next 
LOGGER.info("End Certifs")

当然,下面的测试代码失败了:

Dim wq As Net.WebRequest = Net.WebRequest.Create("https://<URL>")
Dim reader As IO.StreamReader = New IO.StreamReader(wq.GetResponse.GetResponseStream)
LOG.info(reader.ReadToEnd)

但是,如果我使用具有证书的用户帐户运行服务,它就会运行。我做错了什么?

附加问题:有没有办法使用服务帐户运行 Internet Explorer 来执行证书安装? (作为一种解决方法)

【问题讨论】:

  • 唯一的方法是在服务的模拟上下文中运行并查询“CurrentUser\My”存储。
  • @Crypt32,您的意思是向服务帐户添加证书毫无意义?如果可以,为什么可以通过 MMC 实现?
  • 这是 .NET Framework API 的限制。 CryptoAPI 提供了这样的功能,它没有在 .NET 中实现。
  • .NET 在X509Store 类后面使用CertOpenStore 函数。 CertOpenStore 支持服务帐户存储,.NET 实现不支持,因为它没有实现。

标签: .net vb.net windows-services windows-server-2008 x509certificate2


【解决方案1】:

.NET 不支持在服务帐户存储中查找证书。底层 API CertOpenStore function 通过 CERT_SYSTEM_STORE_CURRENT_SERVICE 和 CERT_SYSTEM_STORE_SERVICES 值支持服务帐户存储。 .NET 仅支持 StoreLocation 枚举中的 CERT_SYSTEM_STORE_LOCAL_MACHINE 和 CERT_SYSTEM_STORE_CURRENT_USER 值。

MMC 使用本机 API,因此您可以从 MMC 访问服务证书存储。这是 .NET 中的一种已知限制。克服它的唯一方法是直接使用CertOpenStore 函数(通过p/invoke)。

【讨论】:

  • 我对@9​​87654328@ 的评论是否相关?如果是这样,您介意我填写您的答案吗?
  • 这与深度调查有关。但一般来说,答案在StoreLocation枚举中找到。我已经在我的回答中添加了这个参考。
【解决方案2】:

一旦我也遇到过类似的行为......让我们看看下面的代码是否可以帮助你,记住我们的证书是个人证书:

X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certificates = store.Certificates.Find(X509FindType.FindByIssuerName, "test.supportxxxx@test.com", true);
if (certificates.Count > 0)
 {
     // certificate found            
 }

【讨论】:

  • 谢谢,我刚试过,它适用于普通帐户(即找到证书并且 HTTPS 连接成功,但如果服务使用服务帐户运行则不行)。
猜你喜欢
  • 2011-06-20
  • 1970-01-01
  • 2017-02-08
  • 2012-09-29
  • 2017-12-10
  • 2015-07-31
  • 2010-11-28
  • 2012-10-09
  • 1970-01-01
相关资源
最近更新 更多