【发布时间】: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