使用 C#,如何以编程方式确定 Windows 证书存储中的证书是否已被禁用

Using C#, how to programmatically determine if a certificate in a Windows certificate store has been disabled

我目前正在使用 HTTPS 改进经过相互身份验证的 client/server 应用程序之间的通信。我目前正在将验证逻辑构建到 C# 客户端中,以帮助识别 TLS 连接失败时的配置问题。在验证连接时,我验证了服务器提供的根 CA 证书是否安装在客户端的适当存储中并且有效。我正在使用 X509Store 提取 X509Certificate2,并使用 X509Chain 对其进行验证。

我的问题是,即使证书已通过 MMC 禁用,证书也会报告为有效。因此 TLS 连接将失败,尽管链报告为有效。

这种情况不太可能发生,但我想通过报告类似 "Could not connect because root CA is disabled."

的方式来处理

任何人都可以指出可以进行 .NET 或 Win32 调用以确定证书 "Certificate Purposes" 的值的方向吗?或者阅读 "Certificate Status" 以获得证书?

我通读了 MSDN 列出的 System.Security.Cryptography 命名空间中的内容,并开始研究 CryptoAPI 和 CNG,但到目前为止没有找到任何东西。

谢谢!

该对话框没有 "disable" 证书,因此禁用它 "for all purposes"。这意味着它被视为具有用于 EKU 验证目的的空增强型密钥使用扩展。

通常根证书(或中间 CA 证书)不会有 EKU 扩展,因此如果您使用任何 ApplicationPolicy 值进行链构建,它将是匹配的。一旦将其设置为禁用所有用途,您将收到链错误 X509ChainStatusFlags.NotValidForUsage.

如果您想构建一些东西来验证 TLS,您可以检查服务器身份验证或客户端身份验证 EKU(取决于您要检查的内容):

// Server EKU or Client EKU
Oid eku = forServer ? new Oid("1.3.6.1.5.5.7.3.1") : new Oid("1.3.6.1.5.5.7.3.2");

// Test if it's valid for that purpose
chain.ChainPolicy.ApplicationPolicy.Add(eku);

如果您想要 "Disable" 一个根 CA,请将证书的副本添加到不允许的存储区(在 UI 中称为 "Untrusted Certificates")。这将导致链构建产生 X509ChainStatusFlags.ExplicitDistrust.