我正在使用以下代码来评估链中每个证书的根CA状态:
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
,该Extension.CertificateAuthority
依次包含组成该链的证书的数组。我不确定我们是否可以依靠数组中元素的顺序来确定顶级根CA。我找到了this和this,但是第一个依赖于Magic Strings™,第二个依赖于一个可选字段。而且,上面的
True
属性也无法将其范围缩小。如我们所见,链中的两个证书将此属性设置为X509Certificate2
。Certificate.IssuerThumbprint
的公共属性似乎不包含任何可用于可靠地标识链中发行者的内容。最方便的是类似X509ChainPolicy.ExtraStore
之类的东西。显然,由于该链是首先构建的,因此可以某种方式获得此信息。而且我很难考虑在API中忽略这种简单功能的可能性。
我一定在某个地方想念它。
- 编辑 -
我找到了属性,该属性似乎包含除我们追求的证书以外的所有证书。在这里,这是一个简单的排除问题:
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的可靠方法吗?
最佳答案
ChainElements从最叶到最根的顺序。因此,只要您没有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;
}
关于.net - 如何确保我们从链中获得最顶级的根CA证书?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43359089/