如何在 C# 中将 SSL 证书与 HttpWebRequest 结合使用?

发布于 2024-10-21 22:15:35 字数 2141 浏览 7 评论 0原文

目前,我正在编写一个实用程序应用程序,它将连接到给定的 IP 和端口,并使用 HttpWebRequest 检查 SSL 证书中的信息。当我尝试提取证书时,出现抛出异常的错误。异常似乎是因为处理 SSL 证书的行为似乎触发了另一项验证检查。

这是代码,也许有人可以向我展示更好的方法来执行此操作,或者如果我遗漏了某些内容。我不在乎 SSL 证书是否已过期或与 URL 不匹配。这些都与我正在做的事情无关。

当我将委托中的 X509Certificate 分配给新变量并查看调试器中的变量时,所有属性均显示 SSLCert.Issuer 引发了“System.Security.Cryptography.CyrptographyException”类型的异常

当我尝试访问 SSLCert 的属性时,抛出以下异常:m_safeCertContext 是无效句柄

我会搜索该异常,但所有内容都指向无效证书,如果证书已过期,对于我要连接的 IP 和端口组合来说可能是这样。但由于我使用 IP 连接到 IP,而不是任何与通用名称匹配的内容,所以我希望如此,并且可以不在乎,因为我仍然需要这些信息。

代码如下,我还对哪些不起作用和哪些起作用添加了一些注释。

 // To get around the SSL validation in the HttpWebRequest
        System.Net.ServicePointManager.ServerCertificateValidationCallback =
            delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                        System.Security.Cryptography.X509Certificates.X509Chain chain,
                        System.Net.Security.SslPolicyErrors sslPolicyErrors)
            {
                // The below works but isn't what I want. CertName and ExpireDate are both Strings
                this.CertName = ProcessSubject(certificate.Subject);
                this.ExpireDate = certificate.GetExpirationDateString();
                // The below works but the X509Certificate SSLCert shows exceptions in the debugger for most of the properties.
                this.SSLCert = certificate;

                return true; // **** Always accept
            };
        HttpWebRequest myRequest = (HttpWebRequest)System.Net.WebRequest.Create("https://" + this.IP + ":" + this.Port + "/SSLCheck.html");
        myRequest.KeepAlive = false;
        myRequest.Method = "GET";

        try
        {
            HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
        }
        catch (Exception e)
        {
            if (e.Message != "The remote server returned an error: (404) Not Found.")
            {
                throw Exception("Error");
            }

        }

        // THE BELOW FAILS
        this.CertName = this.SSLCert.Subject;

Currently I'm writing a utility application that will connect to a given IP and port and check the information in the SSL certificate using HttpWebRequest. When I try to extract the certificate I get an error that an exception was thrown. The exception seems to be because the act of coping the SSL certificate seems to trigger yet another validation check.

Here is the code, and maybe someone can either show me a better way to do this or if I am missing something. I don't care if the SSL Certificate is expired or doesn't match the URL. None of that is relevant for what I'm doing.

When I assign the X509Certificate in the delegate to a new variable, and look at the variable in the debugger, all the properties show SSLCert.Issuer threw an exception of type 'System.Security.Cryptography.CyrptographicException'

When I try to access a property of SSLCert, I get the following Exception thrown: m_safeCertContext is an invalid handle

I'be searched for that exception, but everything points to an invalid certificate, which might be true if the certificate is expired, and might be true for the IP and port combination I am connecting to. But since I am connecting to the IP using the IP and not anything that would match the common name, I expect that and could care less as I still need the information.

The code is below, I put some comments in as well for what doesn't work and what does work.

 // To get around the SSL validation in the HttpWebRequest
        System.Net.ServicePointManager.ServerCertificateValidationCallback =
            delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                        System.Security.Cryptography.X509Certificates.X509Chain chain,
                        System.Net.Security.SslPolicyErrors sslPolicyErrors)
            {
                // The below works but isn't what I want. CertName and ExpireDate are both Strings
                this.CertName = ProcessSubject(certificate.Subject);
                this.ExpireDate = certificate.GetExpirationDateString();
                // The below works but the X509Certificate SSLCert shows exceptions in the debugger for most of the properties.
                this.SSLCert = certificate;

                return true; // **** Always accept
            };
        HttpWebRequest myRequest = (HttpWebRequest)System.Net.WebRequest.Create("https://" + this.IP + ":" + this.Port + "/SSLCheck.html");
        myRequest.KeepAlive = false;
        myRequest.Method = "GET";

        try
        {
            HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
        }
        catch (Exception e)
        {
            if (e.Message != "The remote server returned an error: (404) Not Found.")
            {
                throw Exception("Error");
            }

        }

        // THE BELOW FAILS
        this.CertName = this.SSLCert.Subject;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

可遇━不可求 2024-10-28 22:15:35

这只是我的猜测。我认为正在发生的事情是,.NET 使用 SSL 握手中传递的证书信息来创建一个在委托中传递给您的证书对象。委托仅用于验证目的。调用完成后,.NET 关闭证书的安全句柄。这就是尝试在回调之外访问证书时调用失败的原因。

为了解决这个问题,您可以在委托内部序列化证书,并在委托外部反序列化它。

This is just a guess on my part. WHat I think is happening is that the certificate info coming through in the SSL handshake is used by .NET to create a cert object that is passed to you in the delegate. The delegate is only to be used for the purpose of validation. After the call completes, .NET closes the safe handle of the certificate. THat is why the call fails when trying to access the certificate outside the callback.

TO get around this, you can serialize the certificate inside the delegate, and deserialize it outside the delegate.

寻梦旅人 2024-10-28 22:15:35

(根据下面的评论进行编辑)

我想您需要做的是创建一个自定义类并将所需的数据存储在委托代码中,而不是传递实际的证书引用。

(Edit from our comments below)

I suppose what you need to do is create a custom class and store the data you need in it inside the delegate code, rather than pass around the actual certificate reference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文