我们碰巧运行一个公开https://
端点的REST API服务。最近我们更改了我们的SSL证书,一些用户(主要是libcurl和Java用户)抱怨他们不再能够验证证书,他们的程序拒绝连接到我们的服务。其他用户,包括.NET用户,没有发现任何问题。 Firefox也很乐意使用该证书在网站上打开页面。
我们需要制作一些代码,以便在我们在生产中使用证书之前尽可能地验证证书。
我制作了一段代码,为证书创建了一个X509Certificate2
对象,然后从中尝试X509Chain.Build()
:
var certDataArray = File.ReadAllBytes( path );
var cert = new X509Certificate2( certDataArray, password );
var chain = new X509Chain();
var result = chain.Build(cert);
var status = chain.ChainStatus;
此代码对我们之前的证书(尚未过期)运行正常并失败(Build()
返回false
而X509Chain.ChainStatus
包含许多元素 - X509ChainStatusFlags.RevocationStatusUnknown
, X509ChainStatusFlags.PartialChain
,X509ChainStatusFlags.OfflineRevocation
)。因此,对于此特定证书,此检查就足够了。
X509Chain.Build()
是否足以确保我们所有用户都能成功验证证书?是否需要进行其他检查?
答案 0 :(得分:3)
X509ChainStausFlags.PartialChain
代码是您遇到问题的标志。链中的至少一个证书a)没有已经在本地证书存储中的颁发者,以及b)没有可解析的授权信息访问扩展,该扩展允许系统下载证书(尽管这也可能是网络错误)。
如果缺少的证书是root,则将其提供给chain.ChainPolicy.ExtraStore(在调用Build之前)会将X509ChainStatusFlags.PartialChain
更改为X509ChainStatusFlags.UntrustedRoot
。如果它是一个中间体,那么它很可能会成功地建立链条。
OfflineRevocation
代码看起来很奇怪,因为你没有指定X509RevocationMode.Offline(至少在这里不在你的代码片段中)。