【问题标题】:How do I use SSL certificates with HttpWebRequest in C#?如何在 C# 中将 SSL 证书与 HttpWebRequest 一起使用?
【发布时间】:2011-03-11 16:02:33
【问题描述】:

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

这是代码,也许有人可以告诉我一个更好的方法来做到这一点,或者如果我遗漏了什么。我不在乎 SSL 证书是否已过期或与 URL 不匹配。这些都与我正在做的事情无关。

当我将委托中的 X509Certificate 分配给一个新变量,并查看调试器中的变量时,所有属性都显示 SSLCert.Issuer 抛出了类型为“System.Security.Cryptography.CyrptographicException”的异常

当我尝试访问 SSLCert 的属性时,我收到以下异常:m_safeCertContext is an invalid handle

我正在搜索该异常,但所有内容都指向无效证书,如果证书已过期,这可能是正确的,并且对于我正在连接的 IP 和端口组合可能是正确的。但由于我使用 IP 连接到 IP,而不是任何与公用名匹配的东西,我希望这样并且可能不太关心,因为我仍然需要信息。

代码如下,我也放了一些cmets来说明什么不起作用,什么起作用。

 // 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;

【问题讨论】:

  • HttpWebRequest 中有很多关于使用 SSL 和证书的问题和答案。您是否查看了右侧的“相关”问题,或者搜索过 [ssl certificate httpwebrequest]?
  • 是的,几乎每个人都在问如何使用我没有使用的客户端证书,或者由于我已经在处理的无效证书而在 HttpWebRequest 中出现错误。
  • 我应该补充一下,最大的问题是我想将 X509Certificate 复制到另一个 X509Certificate 类型变量,当我执行“this.SSLCert = certificate;”时 .NET 似乎再次验证证书/跨度>
  • 您的示例失败时抛出的详细异常是什么?如果可以,请将其添加到您的 OP...
  • 我添加了更多信息以及抛出的异常和错误。

标签: c# ssl httpwebrequest x509certificate x509


【解决方案1】:

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

要解决这个问题,您可以在委托内部序列化证书,并在委托外部对其进行反序列化。

【讨论】:

  • 谢谢,这对我有帮助(只需要一个证书属性,所以我将它分配给委托的类作用域变量)。
【解决方案2】:

(从下面我们的 cmets 编辑)

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

【讨论】:

  • 不幸的是同样的问题。虽然委托接受了 X509Certificate 的类型,但实际传入的类型是 X509Certificate2,所以我只是将其转换为原来的类型。虽然我确实尝试过并重新检查,但同样的问题。
  • 也许尝试制作一个会员克隆?
  • 这是一个很好的尝试,但奇怪的是,我认为该方法是 MSDN 站点上的受保护方法,但由于某种原因,它似乎不可用。 VS 将其突出显示为错误并且无法编译。智能感知也不会将其显示为有效方法。
  • 这里有一些有趣的东西。当我在委托中并执行分配时,它显示 SSLCert 很好,但是,在我退出委托之前,它似乎不会在内部引发异常。
  • 我的监督(即 MemberwiseClone 受到保护)。我想您需要做的是创建一个自定义类并将您需要的数据存储在委托中,而不是传递实际的证书引用。
猜你喜欢
  • 1970-01-01
  • 2012-03-03
  • 2017-06-12
  • 2013-08-03
  • 2011-02-16
  • 1970-01-01
  • 2010-10-06
  • 2012-09-19
  • 1970-01-01
相关资源
最近更新 更多