.net 如何确保我们';正在从链中获取最顶层的根CA证书?
我正在使用此代码评估链中的每个证书的根CA状态:.net 如何确保我们';正在从链中获取最顶层的根CA证书?,.net,ssl,ssl-certificate,x509certificate2,.net,Ssl,Ssl Certificate,X509certificate2,我正在使用此代码评估链中的每个证书的根CA状态: Function GetRootCaCertificates(Chain As X509Chain) As IEnumerable(Of X509Certificate2) With Chain.ChainElements.Cast(Of X509ChainElement) With .Select(Function(Element As X509ChainElement) Element.Certificate) Ret
Function GetRootCaCertificates(Chain As X509Chain) As IEnumerable(Of X509Certificate2)
With Chain.ChainElements.Cast(Of X509ChainElement)
With .Select(Function(Element As X509ChainElement) Element.Certificate)
Return .Where(Function(Certificate As X509Certificate2)
With Certificate.Extensions.Cast(Of X509Extension)
With .Where(Function(Extension As X509Extension) TypeOf Extension Is X509BasicConstraintsExtension)
With .Cast(Of X509BasicConstraintsExtension)
Return .Where(Function(Extension As X509BasicConstraintsExtension) Extension.CertificateAuthority = True).Count > 0
End With
End With
End With
End Function).ToList
End With
End With
End Function
它运行良好,但在当前情况下,它将返回两个StartCom证书:
(是的,我知道StartCom已经退市,我将在本周晚些时候处理此事。)
ServerCertificateValidationCallback
委托接收X509Chain
,该链又包含组成链的证书数组。我不相信我们可以依靠数组中元素的顺序来确定顶级根CA
我找到了和,但第一个依赖于魔术弦™ 第二个依赖于可选字段。而且上面的扩展名.CertificateAuthority
属性也没有将其缩小到足够的范围。如我们所见,链中的两个证书将此属性设置为True
X509Certificate2
的公共属性似乎不包含任何我们可以用来可靠识别其链中发行人的内容。最方便的是类似于Certificate.IssuerThumbprint
或类似的东西
显然,这些信息在某种程度上是可用的,因为该链是在第一时间构建的。我很难考虑这个简单的功能在API中被忽略的可能性
我一定是在什么地方错过了
--编辑--
我找到了X509ChainPolicy.ExtraStore
属性,它似乎包含除我们要查找的证书之外的所有证书。在这里,这是一个简单的排除问题:
Dim oCertificates As List(Of X509Certificate2)
Dim oThumbprints As IEnumerable(Of String)
oThumbprints = Chain.ChainPolicy.ExtraStore.Cast(Of X509Certificate2).Select(Function(Certificate As X509Certificate2) Certificate.Thumbprint)
oCertificates = Chain.ChainElements.Cast(Of X509ChainElement).Select(Function(Element As X509ChainElement) Element.Certificate).ToList
oCertificates.RemoveAll(Function(Certificate As X509Certificate2) oThumbprints.Contains(Certificate.Thumbprint))
这是在链中查找顶级根CA的可靠方法吗?链元素按从最叶到最根的顺序排列。因此,只要您没有得到PartialChain错误,它就是最后一个ChainElement的证书
private static X509Certificate2 GetRootCertificate(X509Chain chain)
{
// Assumes that chain.Build was already called
X509ChainElement chainElement = chain.ChainElements[chain.ChainElements.Count - 1];
foreach (X509ChainStatus status in chainElement.ChainElementStatus)
{
if (status.Status == X509ChainStatusFlags.PartialChain)
{
return null;
}
}
return chainElement.Certificate;
}
…这是100%可靠的排序顺序?(见我的编辑)是的,1号表示0,2号表示1,等等,就是这样。谢谢