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

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

问题描述:

我目前正致力于使用HTTPS优化相互验证的客户端/服务器应用程序之间的通信。我目前正在将验证逻辑构建到C#客户端中,以帮助识别TLS连接失败时的配置问题。在验证连接时,我验证服务器提供的根CA证书安装在客户端,相应的存储区中并且有效。我正在使用X509Store来拉动X509Certificate2,并使用X509Chain进行验证。使用C#,如何以编程方式确定Windows证书存储区中的证书是否已被禁用

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

Certificate Properties

这是一个不太可能的情况下,只有一个我想通过报告类似处理“无法连接,因为根CA被禁用。”

任何人都可以指向一个.NET或Win32调用的方向来确定证书的“证书目的”值吗?或者阅读证书的“证书状态”?

Certificate Status

我通过什么在System.Security.Cryptography命名空间MSDN上市阅读,并开始寻找到的CryptoAPI和CNG,但至今没有发现任何东西。

谢谢!

该对话框没有“禁用”证书,因此“出于所有目的”禁用了该证书。这意味着它为了EKU验证的目的而被视为具有空的增强型密钥用法扩展。

通常情况下,根证书(或中间CA证书)不会有EKU扩展名,所以如果使用任何ApplicationPolicy值进行链构建,它将会匹配。一旦你将其设置为禁用的所有目的,你会得到一个链错误X509ChainStatusFlags.NotValidForUsage

如果你想建立的东西用于验证TLS你检查服务器身份验证或客户端身份验证EKUs(取决于你检查什么):

// 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中称为“不可信证书”)。这将导致链式生产X509ChainStatusFlags.ExplicitDistrust

+0

杰出!感谢您的详细解释。由于我正在检查根CA,而不是SSL证书本身,所以它没有EKU扩展名(完全如您所说)。然而,将“Key Usage”(2.5.29.15)的oid添加到ApplicationPolicy中就像一个魅力。 –

+0

我会说这是不可行的解决方案。事实上,并非所有浏览器都要求完整链对指定用途有效,并且仅在叶证书仅具有期望的用途时才检查。如果你想通过属性获得根CA证书使用 - 请检查它。因为在中级CA级别禁止使用时可能会出现这种情况。结果,根CA可以,但代码将失败,而连接正常工作。 – Crypt32

+0

@ crypt32 EKU必须是一个合适的子集。如果中间块阻止EKU,叶子不能拥有它。他说他用于检查的关键用法是无关紧要的,因为它要求从EKU设置它的OID永远不会打,但是当没有EKU存在时将被允许。 – bartonjs