【问题标题】:Make X509Certificate2 accessible after validation via ServerCertificateCustomValidationCallback通过 ServerCertificateCustomValidationCallback 验证后使 X509Certificate2 可访问
【发布时间】:2021-03-17 19:08:37
【问题描述】:

我正在使用 HttpClientHandler 和自定义 ServerCertificateCustomValidationCallback

在请求完成后,我需要或至少希望拥有对证书链和服务器证书的访问权限。 目前我只是将它们都放在类变量中以供以后访问。

这可能吗?

我现在看到的行为是验证后两个对象都无法访问。 当我尝试在我的调试器中检查服务器证书时,我目前得到一个System.Security.Cryptography.CryptographicException。链似乎是空的。

【问题讨论】:

    标签: c# x509certificate2


    【解决方案1】:

    您面临的问题是因为在离开回调后释放了对象。您可以将证书复制到局部变量,如下所示:

    class MyClass {
        static X509Certificate2 localCert; // must be static
        void MyMethod() {
            ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, error) =>
            {
                localCert = new X509Certificate2(cert.RawData);
                // continue validation and return value
               ...
            };
            // do TLS connection
            ...
        }
    }
    

    链复制有点复杂,因为你不能序列化它。但是,您可以尝试使用 p/invoke 并通过调用 CertDuplicateCertificateChain 函数并将现有链句柄作为参数传递来复制链句柄。也就是说,创建另一个 X509Chain 类型的静态字段并在回调函数中以这种方式分配它:

    localChain = new X509Chain(Win32.CertDuplicateCertificateChain(chain.ChainContext));
    

    函数定义可能是这样的:

    static class Win32 {
        [DllImport("crypt32.dll", SetLastError = true)]
        public static extern IntPtr CertDuplicateCertificateChain(IntPtr pChainContext);
        [DllImport("crypt32.dll", SetLastError = true)]
        public static extern void CertFreeCertificateChain(IntPtr pChainContext);
    }
    

    不要忘记手动处理本地链实例以避免内存泄漏。我还没有测试过这种复制链的方法,但这是我首先要尝试的。

    【讨论】:

    • 我设法使用Export():byte[]Import(byte[]):void 方法复制了服务器证书。您的链条方法确实有效。我假设我只是将 ChainContext 传递给 CertFreeCertificateChain() 或者 .Dispose() 足够了吗?
    • Dispose 就足够了。在以前的 .NET 版本中,X509Chain 没有实现 IDisposable,在这些情况下您必须调用非托管函数。而且不需要导出/导入证书,只需从X509Certificate2.RawData构造本地字段,更简单,更快捷。
    猜你喜欢
    • 2015-04-12
    • 1970-01-01
    • 2013-05-12
    • 2016-04-18
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多