使用ServerCertificateValidationCallback的最佳实践

我正在开发一个在两个后端服务器之间使用一些HTTP通信的项目。 服务器使用X509证书进行身份validation。 不用说,当服务器A(客户端)建立与服务器B(服务器)的连接时,存在SSL / TLSvalidation错误,因为使用的证书不是来自受信任的第三方权限。

通常,处理它的方法是使用ServicePointManager.ServerCertificateValidationCallback ,例如:

 ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, error) => { return cert.GetCertHashString() == "xxxxxxxxxxxxxxxx"; }; 

这种方法有效,除非它不理想。 它本质上做的是覆盖应用程序完成的每个http请求的validation过程。 因此,如果另一个类将尝试运行HTTP请求,它将失败。 此外,如果另一个类为了自己的目的重写ServicePointManager.ServerCertificateValidationCallback ,那么我的通信开始突然失败。

想到的唯一解决方案是创建一个单独的AppDomain来执行客户端HTTP请求。 这可行,但实际上 – 只有这样才能执行HTTP请求是愚蠢的。 开销将是惊人的。

考虑到这一点,有没有人研究过.NET中是否有更好的实践,这将允许访问Web服务,同时处理客户端SSL / TLSvalidation而不影响其他Web客户端?

在.NET 4.5+中使用的可接受(安全)方法是使用HttpWebRequest . ServerCertificateValidationCallback HttpWebRequest . ServerCertificateValidationCallback 。 在特定的请求实例上分配该回调将仅针对请求更改validation逻辑,而不会影响其他请求。

 var request = (HttpWebRequest)WebRequest.Create("https://..."); request.ServerCertificateValidationCallback += (sender, cert, chain, error) => { return cert.GetCertHashString() == "xxxxxxxxxxxxxxxx"; }; 

不使用HttpWebRequest的代码的替代方案,以及无法在证书存储中安装可信证书的环境:检查回调的错误参数,该参数将包含在回调之前检测到的任何错误。 这样,您可以忽略特定哈希字符串的错误,但仍接受通过validation的其他证书。

 ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, error) => { if (cert.GetCertHashString() == "xxxxxxxxxxxxxxxx") { return true; } else { return error == SslPolicyErrors.None; } }; 

参考: https : //msdn.microsoft.com/en-us/library/system.net.security.remotecertificatevalidationcallback(v=vs.110).aspx

请注意,这仍将影响同一appdomain中的其他Web客户端实例(它们都将接受指定的哈希字符串),但至少它不会阻止其他证书。

此方案的直接方法应该是在客户端计算机上的受信任根存储中安装两个自生成的证书。 当您执行此操作时,您将收到安全警告,因为证书无法通过Thawte或类似程序进行身份validation,但在此之后,常规安全通信应该起作用。 IIRC,您需要在受信任的根目录中安装完整(公钥和私钥)版本才能使用。