【问题标题】:X509Certificate2.Verify wrongly verifies bogus certificateX509Certificate2.Verify 错误地验证了伪造的证书
【发布时间】:2017-07-14 18:23:22
【问题描述】:

在我的应用程序中,我在客户端证书上调用 .NET 方法 X509Certificate2.Verify,有时它不应该返回 True(有效)。当我故意试图愚弄它时,就会发生这种情况。

我有这样的代码:

   ' Obtain a client cert in an application-dependent way.
   Dim clientCert As X509Certificate2 = GetX509Certificate2()
   ' Don't call .Verify on the entire certificate itself, as it will
   ' return False unless the client certificate itself is trusted 
   ' by the system, not just the issuer.  Instead, loop through the
   ' chain, considering the cert valid if any element of the chain
   ' is trusted.
   Dim chain As X509Chain = New X509Chain()
   chain.Build(clientCert)
   For Each element In chain.ChainElements
       ' ToDo: figure out why the Verify method apparently can be fooled 
       ' by a cert whose signer DN is the same as a trusted cert.
       isTrustedCertificate = element.Certificate.Verify() And
                              IsDateValid(element.Certificate)
       If isTrustedCertificate Then
           Exit For
       End If
   Next

如果证书的颁发者与 Window 存储中的受信任证书具有完全相同的专有名称,则此代码认为证书有效。 更重要的是,当我检查与假 CA 对应的链元素时,它会报告实际有效 CA 的指纹,而不是假 CA 的指纹。很奇怪。

当然,使用任意 DN 创建您自己的伪造证书颁发机构证书很容易。这意味着您可以创建自己的客户端证书并让我的应用程序信任它们,只要您知道我的 Windows 商店中受信任证书的 DN。坏消息。

我知道 Windows 有能力检测这样的伪造证书,因为如果我将 IIS 虚拟目录配置为需要客户端证书并使用由伪造 CA 颁发的客户端证书,IIS 会正确返回 HTTP 403 错误。但是,在我的应用程序中,上述 .NET 方法并不那么聪明。

我的 .NET 代码做错了什么?

谢谢。


更新:

看来我的问题有两个:

  • clientCert.Verify() 返回 False,因为系统无法找到证书吊销信息。
  • 我未能检查chain.Build(clientCert) 的结果。它为好的证书返回 True,为伪造的证书返回 False。

我不知道如何更改 Verify 对整个证书使用的策略,所以我做了以下更改:

  • 我为 chain.Build 设置了一个非默认策略以使用,当没有可用的撤销信息时忽略问题。
  • 我检查了chain.Build的结果

这是最终代码:

Dim isTrustedCertificate As Boolean = False
Dim chain As X509Chain = New X509Chain()
' Set the chain policy to not complain if the revocation status is unknown.
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown _
     Or X509VerificationFlags.IgnoreEndRevocationUnknown
' The chain will fail to build if the issuer is untrusted.
' Checking the result of chain.Build seems to be important to detecting forged certs.
Dim bChainOK As Boolean = chain.Build(clientCert)
If bChainOK Then
    For Each element In chain.ChainElements
        isTrustedCertificate = element.Certificate.Verify() And
                                IsDateValid(element.Certificate)
        If isTrustedCertificate Then
            Exit For
        End If
    Next
End If

【问题讨论】:

    标签: client-certificates x509certificate2


    【解决方案1】:

    根据 X509Certificate2.Verify 文档

    此方法为证书构建一个简单的链并将基本策略应用于该链。如果您需要有关失败的更多信息,请直接使用 X509Chain 对象验证证书。

    那你做错了什么?每次调用X509Certificate2.Verify() 时,您都在构建链。您的虚假 CA 永远不会被考虑,因为 Verify 方法使用来自 Windows 证书存储的信息构建自己的链,并使用一些默认策略对其进行验证。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-30
      • 2015-04-12
      • 1970-01-01
      • 1970-01-01
      • 2021-06-27
      • 2018-12-25
      • 2012-06-25
      • 1970-01-01
      相关资源
      最近更新 更多