In meiner Anwendung rufe ich die .NET-Methode X509Certificate2.Verify auf einem Client-Zertifikat und manchmal gibt es True (gültig), wenn es nicht sollte. Dies geschieht, wenn ich bewusst versuche, es zu täuschen.X509Certificate2.Verify falsch prüft gefälschtes Zertifikat
Ich habe Code wie folgt aus:
' 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
Dieser Code hält ein Zertifikat gültig, wenn deren Emittent exakt die gleichen eindeutigen Namen als vertrauenswürdiges Zertifikat im Fenster Speicher hat. Wenn ich außerdem das Kettenelement, das der gefälschten CA entspricht, inspiziere, meldet es den Fingerabdruck der tatsächlichen gültigen CA und nicht die des falschen. Seltsam.
Natürlich ist es einfach, ein eigenes gefälschtes Zertifizierungsstellenzertifikat mit einem beliebigen DN zu erstellen. Dies bedeutet, dass Sie Ihre eigenen Clientzertifikate erstellen können und diese von meiner Anwendung als vertrauenswürdig eingestuft werden, solange Sie den DN eines vertrauenswürdigen Zertifikats in meinem Windows-Speicher kennen. Schlechte Nachrichten.
Ich weiß, dass Windows gefälschte Zertifikate wie dieses erkennen kann. Wenn ich ein virtuelles IIS-Verzeichnis so konfiguriere, dass Clientzertifikate und ein Clientzertifikat einer falschen Zertifizierungsstelle erforderlich sind, gibt IIS einen HTTP 403-Fehler korrekt zurück. In meiner Anwendung ist die obige .NET-Methode jedoch nicht so clever.
Was mache ich falsch in meinem .NET-Code?
Danke.
UPDATE:
Es scheint, dass mein Problem war zweifach:
- clientCert.Verify() Falsch zurückkehrte, weil das System nicht in der Lage war cert Widerrufinformationen zu finden.
- Ich konnte das Ergebnis von chain.Build (clientCert) nicht überprüfen. Es gab True für das gute Zertifikat und False für das gefälschte Zertifikat zurück.
Ich weiß nicht, wie die Richtlinie auf dem gesamten cert Verify verwendet zu ändern, indem, so habe ich diese Änderungen:
- ich eine Nicht-Standardrichtlinie für chain.Build zu verwenden, Probleme ignorieren, wenn keine Sperrinformationen verfügbar waren.
- überprüfte ich das Ergebnis der chain.Build
Hier ist der endgültige Code:
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