X509Certificate2.Verify错误地验证伪造证书

时间:2017-02-24 02:42:02

标签: client-certificates x509certificate2

在我的应用程序中,我在客户端证书上调用.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

1 个答案:

答案 0 :(得分:0)

根据X509Certificate2.Verify文档

  

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

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