使用特定CA进行SSL连接

我正在阅读使用.NET Framework 2.0的应用程序中的支持证书,试图确定如何为SSL连接设置CA.

在validation证书下的文章中,MSDN提供了一些代码:

static void ValidateCert(X509Certificate2 cert) { X509Chain chain = new X509Chain(); // check entire chain for revocation chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; // check online and offline revocation lists chain.ChainPolicy.RevocationMode = X509RevocationMode.Online | X509RevocationMode.Offline; // timeout for online revocation list chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 30); // no exceptions, check all properties chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag; // modify time of verification chain.ChainPolicy.VerificationTime = new DateTime(1999, 1, 1); chain.Build(cert); if (chain.ChainStatus.Length != 0) Console.WriteLine(chain.ChainStatus[0].Status); } 

然后呢:

 // override default certificate policy ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(VerifyServerCertificate); 

我觉得我错过了一些非常明显的东西。 例如,我不想要回调 – 我只想说,“建立一个SSL连接,这里是一个值得信赖的CA”。 但我在上面的代码中没有看到。

X509Chain似乎没有添加CA或信任根的add方法。 在回调之前不应该设置CA吗? 但我在上面的代码中没有看到。

在Java中,在加载要使用的特定CA之后,将使用TrustManager (或TrustManagerFactory )完成(例如,请参阅直接在文件系统上使用PEM编码CA证书以获取HTTPS请求? )。

问题 :如何在.Net或C#中设置CA用于SSL连接?

以下代码将避免Windows证书存储并使用文件系统上的CAvalidation链。

function的名称无关紧要。 下面, VerifyServerCertificateSslStream类中的RemoteCertificateValidationCallback相同。 它也可以用于ServicePointManagerServerCertificateValidationCallback

 static bool VerifyServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { try { String CA_FILE = "ca-cert.der"; X509Certificate2 ca = new X509Certificate2(CA_FILE); X509Chain chain2 = new X509Chain(); chain2.ChainPolicy.ExtraStore.Add(ca); // Check all properties chain2.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag; // This setup does not have revocation information chain2.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; // Build the chain chain2.Build(new X509Certificate2(certificate)); // Are there any failures from building the chain? if (chain2.ChainStatus.Length == 0) return false; // If there is a status, verify the status is NoError bool result = chain2.ChainStatus[0].Status == X509ChainStatusFlags.NoError; Debug.Assert(result == true); return result; } catch (Exception ex) { Console.WriteLine(ex); } return false; } 

没有想出如何使用这个链(下面的链chain2 )默认,这样就不需要回调了。 也就是说,将它安装在ssl套接字上,连接将“正常工作”。 而且我还没弄清楚如何安装它以便将其传递给回调。 也就是说,我必须为每次调用回调构建链。 我认为这些是.Net中的架构缺陷,但我可能会遗漏一些明显的东西。