因为CA证书不在根证书存储中,所以在RemoteCertificateValidationCallback()中会出现SslPolicyErrors.RemoteCertificateChainErrors的错误标志;一种可能的方法是显式验证证书链与您自己的X509Certificate2Collection相匹配,因为您没有使用本地存储。
if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors)
{
X509Chain chain0 = new X509Chain();
chain0.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain0.ChainPolicy.ExtraStore.Add(new X509Certificate2(PublicResource.my_ca));
chain0.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
isValid = chain0.Build((X509Certificate2)certificate);
}
你还可以在回调函数中重复使用传递的链,将你的额外证书添加到
ExtraStore集合中,并使用
AllowUnknownCertificateAuthority标志进行验证,因为你添加了不受信任的证书到链中。
你也可以通过编程方式将CA证书添加到受信任根存储区来防止原始错误(当然,这会弹出一个窗口,因为全局添加新的受信任CA根是一个重大安全问题):
var store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite);
X509Certificate2 ca_cert = new X509Certificate2(PublicResource.my_ca);
store.Add(ca_cert);
store.Close();
编辑:对于那些想要清楚地使用您的 CA 测试链的人:
另一个可能性是使用库BouncyCastle
来构建证书链并验证信任。选项很清晰,错误易于理解。如果成功则会构建链,否则将返回异常。以下是示例:
var builderParams = new PkixBuilderParameters(rootCerts,
new X509CertStoreSelector { Certificate = currentCertificate });
builderParams.IsRevocationEnabled = crls.Count != 0;
builderParams.Date = new DateTimeObject(validationDate);
builderParams.AddStore(X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(intermediateCerts)));
builderParams.AddStore(X509StoreFactory.Create("CRL/Collection", new X509CollectionStoreParameters(crls)));
try
{
PkixCertPathBuilderResult result = builder.Build(builderParams);
return result.CertPath.Certificates.Cast<X509Certificate>();
...