允许使用HttpClient的不受信任的SSL证书

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了允许使用HttpClient的不受信任的SSL证书相关的知识,希望对你有一定的参考价值。

我很难让我的Windows 8应用程序通过SSL与我的测试Web API进行通信。

似乎HttpClient / HttpClientHandler没有提供和选项来忽略像WebRequest这样的不受信任的证书使你(尽管用ServerCertificateValidationCallback的“hacky”方式)。

任何帮助将非常感激!

答案

使用Windows 8.1,您现在可以信任无效的SSL证书。您必须使用Windows.Web.HttpClient,或者如果您想使用System.Net.Http.HttpClient,您可以使用我写的消息处理程序适配器:http://www.nuget.org/packages/WinRtHttpClientHandler

Docs在GitHub上:https://github.com/onovotny/WinRtHttpClientHandler

另一答案

我在网上找到了一个似乎运作良好的例子:

首先,你创建一个新的ICertificatePolicy

using System.Security.Cryptography.X509Certificates;
using System.Net;

public class MyPolicy : ICertificatePolicy
{
  public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, 
int certificateProblem)
  {
    //Return True to force the certificate to be accepted.
    return true;
  }
}

然后在发送您的http请求之前使用它,如下所示:

System.Net.ServicePointManager.CertificatePolicy = new MyPolicy();

http://www.terminally-incoherent.com/blog/2008/05/05/send-a-https-post-request-with-c/

另一答案

一个快速而肮脏的解决方案是使用ServicePointManager.ServerCertificateValidationCallback代表。这允许您提供自己的证书验证。验证在整个App域中全局应用。

ServicePointManager.ServerCertificateValidationCallback +=
    (sender, cert, chain, sslPolicyErrors) => true;

我主要用于单元测试,我希望在我正在托管的端点上运行并尝试使用WCF clientHttpClient命中它。

对于生产代码,您可能需要更精细的控制,并且最好使用WebRequestHandler及其ServerCertificateValidationCallback委托属性(请参阅dtb's answer below)。或使用answer ctacke HttpClientHandler。我现在更喜欢这两个中的任何一个,即使我使用我的过去的集成测试,除非我找不到任何其他钩子。

另一答案

看看WebRequestHandler Class及其ServerCertificateValidationCallback Property

using (var handler = new WebRequestHandler())
{
    handler.ServerCertificateValidationCallback = ...

    using (var client = new HttpClient(handler))
    {
        ...
    }
}
另一答案

如果您尝试在.NET标准库中执行此操作,这是一个简单的解决方案,具有在您的处理程序中返回true的所有风险。我把安全留给你。

var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ServerCertificateCustomValidationCallback = 
    (httpRequestMessage, cert, cetChain, policyErrors) =>
{
    return true;
};

var client = new HttpClient(handler);
另一答案

或者您可以在Windows.Web.Http命名空间中使用HttpClient:

var filter = new HttpBaseProtocolFilter();
#if DEBUG
    filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Expired);
    filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
    filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName);
#endif
using (var httpClient = new HttpClient(filter)) {
    ...
}
另一答案

如果这是针对Windows运行时应用程序,则必须将自签名证书添加到项目中并在appxmanifest中引用它。

文档在这里:http://msdn.microsoft.com/en-us/library/windows/apps/hh465031.aspx

如果来自不受信任的CA(如机器本身不信任的私有CA),则需要获取CA的公共证书,将其作为内容添加到应用程序,然后将其添加到清单中。

完成后,应用程序会将其视为正确签名的证书。

另一答案

这里的大多数答案建议使用典型模式:

using (var httpClient = new HttpClient())
{
 // do something
}

因为IDisposable接口。请不要!

微软告诉你原因:

在这里你可以找到幕后发生的详细分析:https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

关于您的SSL问题并基于https://docs.microsoft.com/en-us/azure/architecture/antipatterns/improper-instantiation/#how-to-fix-the-problem

这是你的模式:

class HttpInterface
{
 // https://docs.microsoft.com/en-us/azure/architecture/antipatterns/improper-instantiation/#how-to-fix-the-problem
 // https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient#remarks
 private static readonly HttpClient client;

 // static initialize
 static HttpInterface()
 {
  // choose one of these depending on your framework

  // HttpClientHandler is an HttpMessageHandler with a common set of properties
  var handler = new HttpClientHandler();
  {
      ServerCertificateCustomValidationCallback = delegate { return true; },
  };
  // derives from HttpClientHandler but adds properties that generally only are available on full .NET
  var handler = new WebRequestHandler()
  {
      ServerCertificateValidationCallback = delegate { return true; },
      ServerCertificateCustomValidationCallback = delegate { return true; },
  };

  client = new HttpClient(handler);
 }

 .....

 // in your code use the static client to do your stuff
 var jsonEncoded = new StringContent(someJsonString, Encoding.UTF8, "application/json");

 // here in sync
 using (HttpResponseMessage resultMsg = client.PostAsync(someRequestUrl, jsonEncoded).Result)
 {
  using (HttpContent respContent = resultMsg.Content)
  {
   return respContent.ReadAsStringAsync().Result;
  }
 }
}
另一答案

我没有答案,但我确实有另一种选择。

如果您使用Fiddler2监控流量并启用HTTPS解密,您的开发环境将不会抱怨。这不适用于WinRT设备,例如Microsoft Surface,因为您无法在其上安装标准应用程序。但是你的开发Win8电脑会很好。

要在Fiddler2中启用HTTPS加密,请转到工具>提琴选项> HTTPS(选项卡)>选中“解密HTTPS流量”。

我将继续关注这个线索,希望有人能有一个优雅的解决方案。

另一答案

我在这个允许 Java 使用不受信任的证书进行 SSL/HTTPS 连接

如何处理与Apache HttpClient的无效SSL证书

如何阻止不受信任的证书?

怎样的ssl证书才能被信任?

由于证书不受信任,无法从 Azure SF 连接到外部 https

解决Charles抓包ssl证书信任问题