Xamarin Android问题通过HTTPS连接到具有自签名证书的站点;找不到证书路径的信任锚点。”;

Xamarin Android问题通过HTTPS连接到具有自签名证书的站点;找不到证书路径的信任锚点。”;,android,ssl,xamarin,httpclient,Android,Ssl,Xamarin,Httpclient,我正在尝试对具有2个SSL证书的站点进行HTTPS调用:一个自签名证书和一个由第一个证书签名的证书。当我使用HttpClient向站点发送请求时,控制台会记录一个不受信任的链,显示两个证书,然后打印由java.security.cert.CertPathValidatorException:Trust anchor for certification path not found引起的长堆栈跟踪 我已经在手机上安装了这两个证书,并且在Chrome上导航到该站点时会显示一个受信任的连接(在我安装证

我正在尝试对具有2个SSL证书的站点进行HTTPS调用:一个自签名证书和一个由第一个证书签名的证书。当我使用HttpClient向站点发送请求时,控制台会记录一个不受信任的链,显示两个证书,然后打印由
java.security.cert.CertPathValidatorException:Trust anchor for certification path not found
引起的长堆栈跟踪

我已经在手机上安装了这两个证书,并且在Chrome上导航到该站点时会显示一个受信任的连接(在我安装证书之前,该站点有一个不受信任的连接警告)。我认为问题在于应用程序拒绝信任自签名证书。我无法访问服务器,因此对其证书没有影响,因此安装由可信CA签名的证书是不可行的


我尝试过的解决方案没有奏效。 ServicePointManager.ServerCertificateValidationCallback似乎未运行。

我曾尝试使用自己的函数来调用
ServicePointManager.ServerCertificateValidationCallback
,但我赋予它的委托似乎从未运行过。我在MainActivity.OnCreate方法中有以下代码,但控制台从不记录该消息:

System.Net.ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
{
  Console.WriteLine($"****************************************************************************************************");

  return true;
};
HttpClientHandler.ServerCertificateCustomValidationCallback引发异常。

我尝试使用了一个
HttpClientHandler
并设置了它的
ServerCertificateCustomValidationCallback
,但我得到的信息是:

System.Net.ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
{
  Console.WriteLine($"****************************************************************************************************");

  return true;
};
System.NotImplementedException:方法或操作未实现。在System.Net.Http.HttpClientHandler.set_服务器CertificateCustomValidationCallback(System.Func`5[T1、T2、T3、T4、TResult]值)

设置代码:

HttpClientHandler handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
HttpClient client = new HttpClient(handler);

我在Android和iOS上都能做到这一点

iOS很简单,只需覆盖
ServicePointManager.ServerCertificateValidationCallback

ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
对于Android我使用并创建了一个依赖项服务

在我的Xamarin表单项目中,我添加了一个简单的界面:

public interface IHTTPClientHandlerCreationService
{
  HttpClientHandler GetInsecureHandler();
}
[assembly: Dependency(typeof(HTTPClientHandlerCreationService_Android))]
namespace MyApp.Droid
{
  public class HTTPClientHandlerCreationService_Android : CollateralUploader.Services.IHTTPClientHandlerCreationService
  {
    public HttpClientHandler GetInsecureHandler()
    {
      return new IgnoreSSLClientHandler();
    }
  }

  internal class IgnoreSSLClientHandler : AndroidClientHandler
  {
    protected override SSLSocketFactory ConfigureCustomSSLSocketFactory(HttpsURLConnection connection)
    {
      return SSLCertificateSocketFactory.GetInsecure(1000, null);
    }

    protected override IHostnameVerifier GetSSLHostnameVerifier(HttpsURLConnection connection)
    {
      return new IgnoreSSLHostnameVerifier();
    }
  }

  internal class IgnoreSSLHostnameVerifier : Java.Lang.Object, IHostnameVerifier
  {
    public bool Verify(string hostname, ISSLSession session)
    {
      return true;
    }
  }
}
在我的Xamarin Android项目中,我实现了界面:

public interface IHTTPClientHandlerCreationService
{
  HttpClientHandler GetInsecureHandler();
}
[assembly: Dependency(typeof(HTTPClientHandlerCreationService_Android))]
namespace MyApp.Droid
{
  public class HTTPClientHandlerCreationService_Android : CollateralUploader.Services.IHTTPClientHandlerCreationService
  {
    public HttpClientHandler GetInsecureHandler()
    {
      return new IgnoreSSLClientHandler();
    }
  }

  internal class IgnoreSSLClientHandler : AndroidClientHandler
  {
    protected override SSLSocketFactory ConfigureCustomSSLSocketFactory(HttpsURLConnection connection)
    {
      return SSLCertificateSocketFactory.GetInsecure(1000, null);
    }

    protected override IHostnameVerifier GetSSLHostnameVerifier(HttpsURLConnection connection)
    {
      return new IgnoreSSLHostnameVerifier();
    }
  }

  internal class IgnoreSSLHostnameVerifier : Java.Lang.Object, IHostnameVerifier
  {
    public bool Verify(string hostname, ISSLSession session)
    {
      return true;
    }
  }
}
共享代码要正确设置HttpClient:

switch (Device.RuntimePlatform)
{
  case Device.Android:
    this.httpClient = new HttpClient(DependencyService.Get<Services.IHTTPClientHandlerCreationService>().GetInsecureHandler());
    break;
  default:
    ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
    this.httpClient = new HttpClient(new HttpClientHandler());
    break;
}
交换机(设备运行时平台)
{
case设备。Android:
this.httpClient=新的httpClient(DependencyService.Get().getSecureHandler());
打破
违约:
ServicePointManager.ServerCertificateValidationCallback+=(发件人、证书、链、sslPolicyErrors)=>true;
this.httpClient=new-httpClient(new-HttpClientHandler());
打破
}

您使用的是托管提供程序还是AndroidClientHandler和/或哪个SSL/TLS:BoringSSL或managed?我只是使用常规的
HttpClient
及其默认设置(尝试使用HttpClientHandler时除外)。我正在寻找项目的Android构建设置(项目选项/构建/Android构建/常规选项卡),如果仍然可以使用托管提供程序,请使用AndroidClientHandler和clean/rebuild/retestHttpClient实现:Android.SSL/TLS实现:Native TLS 1.2+。我将HttpClient实现更改为托管,尝试调用时出现异常
System.Net.WebException:无法从传输连接读取数据ion:连接被对等方重置。
。SSL/TLS设置?您在哪里编写此代码,我就遇到了编译器错误!!这对我来说很有效。回答很好。感谢您的回答。它可能在Android项目的MainActivity.cs文件中。我收到此警告:“SSLCertificateSocketFactory.getunsecure(int,SSLSessionCache)'已过时:'已弃用'。此外,对于加载图像,此解决方案似乎不起作用。只有JSON调用起作用。我遵循此解决方案,但仍然未找到证书路径的错误信任锚点。我是否需要在测试设备上安装证书才能起作用?如果需要,是否有人向我演示如何操作?此解决方案是否仅适用于self-s签名证书?实际证书如何?