2

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

在Validating Certificates下的文章的中途,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似乎没有add添加 CA 或信任根的方法。CA不应该在回调之前设置吗?但我在上面的代码中看不到这一点。

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

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

4

1 回答 1

2

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

函数的名称无关紧要。下面,VerifyServerCertificate是与课堂上相同的RemoteCertificateValidationCallback回调SslStream。它也可以用于ServerCertificateValidationCallbackin ServicePointManager

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 中的架构缺陷,但我可能会遗漏一些明显的东西。

于 2014-04-20T09:55:35.913 回答