首页 > 解决方案 > 如何从虚拟服务帐户访问系统私钥?

问题描述

我正在开发使用 SChannel 支持客户端 TLS 连接的 NT 服务。证书通过本地计算机证书管理器 (certlm.msc) 手动安装到称为“公共集线器接口”的自定义证书存储中。该服务已经投入生产几个月了,除了以下问题外,运行平稳。

尽管在 LocalSystem 下一切正常,但为了最大限度地提高安全性,我正在尝试使用虚拟服务帐户,例如“NT Service\Public Hub Interface”。但是,由于帐户受到如此严格的限制,该服务不再有权访问系统的私钥,从而导致 AcquireCredentialsHandle 返回 SEC_E_UNKNOWN_CREDENTIALS。我已经尝试手动和以编程方式授予对各种文件和注册表对象的访问权限,如以下链接中所述,但部分成功 - CAPI 证书有效,但 CNG 无效。

https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/d2a477c4-c366-4a68-8014-83632651bc91/how-to-grant-an-account-access-to-the-certificate-in- a-service-store-programmatically?forum=windowssecurity

https://docs.microsoft.com/en-us/windows/desktop/seccng/key-storage-and-retrieval

https://docs.microsoft.com/en-us/windows/desktop/SecCrypto/modifying-key-container-access

https://www.codeguru.com/cpp/in/internet/security/article.php/c6211/Security-Certificates-Treatment-with-CryptoAPI.htm

还有其他人,但他们几乎都说同样的话。此外,许多解决方案都适用于单个证书,并假设可以直接访问它们,或者至少知道它们的位置。不幸的是,这不是我的情况,因为证书是通过 certlm 从外部安装的,并且单独的自定义证书安装应用程序不在游戏计划中。事实上,如果可能的话,我对访问容器更感兴趣,而不是处理它们的特定内容。此外,还有许多证书,其中没有一个是提前知道的,并且大多数通常在服务运行后安装好。

我宁愿不从本地机器的商店提供者切换到服务的(即当前用户的)商店提供者,特别是因为我非常接近发布并且没有时间修改/重新测试已经工作的代码,更不用说重新- 导入证书以及对操作员进行新程序的再培训。因此,我希望有一种简单可靠的方法来授予服务对 LocalSystem 帐户拥有的系统私钥的相同访问权限。

请注意,该服务是通过 MSI 包安装的,该包使用非托管 C++ 自定义操作 DLL 来执行高级操作,例如配置服务恢复选项和创建证书存储;我计划在安装过程中使用同一个 DLL 来设置所需的访问权限。也就是说,我更喜欢使用外部程序(例如 WinHttpCertCfg.exe 或 CertUtil.exe)的程序解决方案,它甚至可能无法在目标系统上运行,或者如果它必须包含在包中还不存在。

非常感谢您的帮助。

标签: winapivisual-c++windows-servicesprivate-keyschannel

解决方案


推荐阅读