2011-03-11 186 views
8

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

这里是代码,也许有人可以告诉我一个更好的方法来做到这一点,或者如果我失去了一些东西。我不关心SSL证书是否过期或与URL不匹配。这些与我正在做的事无关。

当我指定的委托一个新的变量X509证书,并期待在调试器中的变量,所有属性表明SSLCert.Issuer投掷型“System.Security.Cryptography.CyrptographicException”

的例外

当我尝试访问的sslcert的财产,我得到下面的异常抛出:m_safeCertContext是无效的句柄

I'be搜索的结果异常,但一切都指向一个无效的证书,这可能是如果证书已过期,则为true,IP可能为true和我正在连接的端口组合。但是,由于我使用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; 
+0

这里有很多关于在HttpWebRequest中使用SSL和证书的问题和解答。你有没有看过右边的“相关”问题,或者搜索了[ssl certificate httpwebrequest]? – 2011-03-11 16:13:51

+1

是的,几乎每个人都在问如何使用客户端证书,我没有使用,或者因为无效的证书而在HttpWebRequest中发生错误,我已经处理了这个错误。 – omniplex 2011-03-11 16:19:51

+0

我应该补充说,最大的问题是我想将X509Certificate复制到另一个X509Certificate类型变量,并且当我执行“this.SSLCert = certificate;”时,.NET似乎再次验证了证书。 – omniplex 2011-03-11 16:23:30

回答

0

(编辑从我们下面的评论)

我想你需要做的是创建一个自定义类,并保存您在它需要委托代码中,而不是通过实际的证书周围的数据是什么参考。

+0

不幸的是,同样的问题。当委托接受一种类型的X509Certificate时,实际传入的类型是X509Certificate2,所以我只是将它转换为它的名称。虽然我确实尝试过并重新检查,但同样的问题。 – omniplex 2011-03-11 16:41:06

+0

也许试试做一个成员的克隆呢? – 2011-03-11 16:45:49

+0

这是一个很好的尝试,但奇怪的是,我将该方法看作是MSDN站点上的受保护方法,但是由于某些原因,它似乎不可用。 VS强调它是一个错误,它不会编译。智能感知也不表明它是一种有效的方法。 – omniplex 2011-03-11 16:54:52

1

这只是我的猜测而已。我认为正在发生的事情是,SSL握手中通过的证书信息被.NET用来创建一个在委托中传递给你的证书对象。代表仅用于验证目的。调用完成后,.NET将关闭证书的安全句柄。这就是为什么当试图在回调之外访问证书时呼叫失败。

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

+0

谢谢,这帮了我(只需要一个证书属性,所以我将它分配给代理的类作用域变量)。 – 2016-02-09 20:13:41