如何确保我们从链中获得最顶层的根CA证书?

问题描述 投票:0回答:1

我使用此代码来评估链中每个证书的根 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 证书:

Certificate Chain

(是的,我知道 StartCom 已被摘牌——我将在本周晚些时候处理这个问题。)

ServerCertificateValidationCallback
委托接收
X509Chain
,后者又包含组成链的证书数组。我不相信我们可以依靠数组中元素的顺序来确定顶级根 CA。

我找到了 thisthis,但第一个依赖于 Magic Strings™,第二个依赖于可选字段。上面的

Extension.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 的可靠方法吗?

.net ssl ssl-certificate x509certificate2
1个回答
5
投票
ChainElements 按从最叶到最根的顺序排列。 所以只要你没有收到 PartialChain 错误,它就是最后一个 ChainElement 的证书。

private static X509Certificate2 GetRootCertificate(X509Chain chain) { // Assumes that chain.Build was already called foreach (X509ChainStatus status in chain.ChainStatus) { if (status.Status == X509ChainStatusFlags.PartialChain) { return null; } } X509ChainElement chainElement = chain.ChainElements[chain.ChainElements.Count - 1]; return chainElement.Certificate; }
    
© www.soinside.com 2019 - 2024. All rights reserved.