c# - X509Certificate2.Verify() 总是返回 false

标签 c# client-certificates x509certificate2

面对一个非常奇怪的问题 X509Certificate2.Verify() 为有效证书返回 false。也许有些人以前已经遇到过这种奇怪的情况,并且可以对此有所了解。

我正在使用 openssl 生成用于测试目的的客户端证书。 我创建了一个根 CA 并基于该根 CA 生成了一个客户端证书,并将根 CA 添加到它的链中。

我将根 CA 和客户端证书加载到本地证书存储区,在那里似乎没问题,但是当我从我的 NUnit 代码加载它以测试 X509Certificate2.Verify() 时,它总是返回 false。

enter image description here

这是从商店加载证书的代码:

        X509Store store = new X509Store(StoreName.My);
        string thumbprint = "60 d1 38 95 ee 3a 73 1e 7e 0d 70 68 0f 2d d0 69 1e 9a eb 72";
        store.Open(OpenFlags.ReadOnly);
        var mCert = store.Certificates.Find(
                                X509FindType.FindByThumbprint,
                                thumbprint,
                                true
                              ).OfType<System.Security.Cryptography.X509Certificates.X509Certificate>().FirstOrDefault();
        if(mCert != null)
        {
            var testClientCert = new X509Certificate2(mCert);
        }

这是我刚刚生成的客户端证书: (可以从我的本地计算机正确访问 CRL url)

-----BEGIN CERTIFICATE-----
MIIC7jCCAlegAwIBAgIBATANBgkqhkiG9w0BAQUFADBtMR0wGwYDVQQKExRWaXRh
bEhlYWx0aCBTb2Z0d2FyZTElMCMGA1UECxMcVml0YWxIZWFsdGggU29mdHdhcmUg
Um9vdCBDQTElMCMGA1UEAxMcVml0YWxIZWFsdGggU29mdHdhcmUgUm9vdCBDQTAe
Fw0xNTAyMjcwODQ2MzNaFw0xNjAyMjcwODQ2MzNaMEUxHTAbBgNVBAoTFFZpdGFs
SGVhbHRoIFNvZnR3YXJlMREwDwYDVQQLEwhQbGF0Zm9ybTERMA8GA1UEAxMIVGVz
dFVzZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOkfyjX0PSnRYrBbCC8u
rw7IiFdAUj6frPKEmt0TLAR/4g+NazKdGjRRqxE9mNwX/2zGhIcucfGDVwPtOtiV
opicQEzGiSQkvAc+473MN5D6j3XtBYblALMeMyEYoh3LnHO4K+6kV6XE4BXV/2lV
mAVgXGkZzaayd40DLvg48vPlAgMBAAGjgcUwgcIwCQYDVR0TBAIwADARBglghkgB
hvhCAQEEBAMCB4AwCwYDVR0PBAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMCMDEG
CWCGSAGG+EIBDQQkFiJPcGVuU1NMIENlcnRpZmljYXRlIGZvciBTU0wgQ2xpZW50
ME0GA1UdHwRGMEQwQqBAoD6GPGh0dHA6Ly9wbGF0Zm9ybWRhc2hib2FyZC5ubC52
aXRhbGhlYWx0aC5sb2NhbC9wb3J0YWwvY3JsLmNybDANBgkqhkiG9w0BAQUFAAOB
gQBXYSmZaVu6vnyl94SO4qpNOutsUm4p7fQHehljhZ+aRrXE10rivWCt4g0k961E
PDsp4J0DR6uth6et42pBp8v2gFIGSQY/F7NhmOAsOJvM7z0oIBxMLcclIDTygbRp
KjZZpNjvf+YJasbidosiL4VSeRiCZ+HPzvKDb3wNeafoZA==
-----END CERTIFICATE-----

这是我从浏览器访问时下载的 CRL 文件:

-----BEGIN X509 CRL-----
MIIBMjCBnDANBgkqhkiG9w0BAQUFADBtMR0wGwYDVQQKExRWaXRhbEhlYWx0aCBT
b2Z0d2FyZTElMCMGA1UECxMcVml0YWxIZWFsdGggU29mdHdhcmUgUm9vdCBDQTEl
MCMGA1UEAxMcVml0YWxIZWFsdGggU29mdHdhcmUgUm9vdCBDQRcNMTQwODA3MTQz
OTIyWhcNMTQwOTA2MTQzOTIyWjANBgkqhkiG9w0BAQUFAAOBgQA8MSxAorbxpdDm
1IA2Aqjb/OkZydua1Tm5k5KtHknI4zyYPZb3GzO0eRygpKBSAqtYkxDI6eCv6xgf
+anXT56md+cPGZ+2YvSicxqwP2GL2kymc9mVMTiQieioS1/7apjCIjZEgWxqf3Up
zvy/kNQRg3lII8hYu0idGs9byKZJFQ==
-----END X509 CRL-----

最佳答案

根据X509Certificate2.Verify文档

This method builds a simple chain for the certificate and applies the base policy to that chain. If you need more information about a failure, validate the certificate directly using the X509Chain object.

因此我会尝试使用此代码构建链(用您自己的实现替换 Log 方法,我使用的是 Console.Writeline)

X509Chain chain = new X509Chain();

try
{
    var chainBuilt = chain.Build(testClientCert );
    Log(string.Format("Chain building status: {0}", chainBuilt));

    if (chainBuilt == false)
        foreach (X509ChainStatus chainStatus in chain.ChainStatus)
            Log(string.Format("Chain error: {0} {1}", chainStatus.Status, chainStatus.StatusInformation));
}
catch (Exception ex)
{
    Log(ex.ToString());
}

此代码将告诉您无法验证证书的原因。如果您需要调整链策略,则设置 chain.ChainPolicy 属性即

chain.ChainPolicy = new X509ChainPolicy()
{
    RevocationMode = X509RevocationMode.NoCheck,
    VerificationFlags = X509VerificationFlags.IgnoreNotTimeValid,
    UrlRetrievalTimeout = new TimeSpan(0, 1, 0)
};

关于c# - X509Certificate2.Verify() 总是返回 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28761249/

相关文章:

c# - 使用 = 的条件逻辑运算符

c# - C#同步接口(interface)和实现注释的方法

c# - 是否可以在类中定义任何类型的列表,它可以包含任何类型的列表

ssl - 如何从 Spring-XD 建立双向 SSL 连接

ssl - haproxy 是否支持 OCSP 进行客户端证书验证

c# - 吊销 X509Certificate

c# - Unity接触点无碰撞器

android - 在 Android 设备上生成客户端证书

c# - .Net 中使用套接字通信的点对点相互 SSL 身份验证

c# - 为什么服务器可能收不到附加到使用 HttpClient 的请求的证书?