尽管servicePointManager受到黑客攻击,但WebRequest不能在Xamarin.Forms上与ssl一起使用 [英] WebRequest not working with ssl on Xamarin.Forms, despite servicePointManager hack

查看:70
本文介绍了尽管servicePointManager受到黑客攻击,但WebRequest不能在Xamarin.Forms上与ssl一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个需要从REST API读取的应用程序,该REST API仅可通过https访问.我遇到了在Mono.Security中请求失败的消息,消息是:身份验证或解密失败."

I am writing an application that needs to read from a REST api that is only available over https. I am running into the issue where the request fails in Mono.Security, with the message: "The authentication or decryption has failed."

我进行了研究,发现默认情况下,Mono没有任何受信任的证书.我发现的所有消息来源都说我可以使用

I did my research and found that Mono by default doesn't have any trusted certificates. All the sources I found said that I could use

ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback((sender, certificate, chain, policyErrors) => { return true; });

分别在iOS和Droid项目的Main()和OnCreate()方法中,以覆盖该检查并允许任何ssl证书.即使有了这种解决方法,我仍然遇到相同的错误.我单步执行代码,并确认在iOS和Android上运行时执行了以上代码.

within the Main() and OnCreate() methods in the iOS and Droid projects respectively to override that check and allow any ssl cert. Even with that workaround, I'm still getting the same error. I have stepped through the code and confirmed that the above line is executed when running on iOS and Android.

当访问非https API时,我的代码可以完美运行.这是一个PCL项目,不是共享项目.

My code works perfectly when accessing non-https APIs. This is a PCL, not shared, project.

我在问之前提到了这些问题/资源

I referred to these questions/resources before asking:

  • 忽略Xamarin.Forms(PCL)中的SSL证书错误
  • stackoverflow.com/questions/2675133/c-sharp-ignore-certificate-errors/2675183#2675183
  • bugzilla.xamarin.com/show_bug.cgi?id=6501
  • stackoverflow.com/questions/12287528/webclient-ssl-exception-with-android-4-and-mono-for-android
  • www.mono-project.com/docs/faq/security/
  • Ignore SSL certificate errors in Xamarin.Forms (PCL)
  • stackoverflow.com/questions/2675133/c-sharp-ignore-certificate-errors/2675183#2675183
  • bugzilla.xamarin.com/show_bug.cgi?id=6501
  • stackoverflow.com/questions/12287528/webclient-ssl-exception-with-android-4-and-mono-for-android
  • www.mono-project.com/docs/faq/security/

这是到目前为止的代码:

Here is the code so far:

public class PawPrintsDataConnection
{
    private string response = "";
    private Task<string> StartWebRequest(string url)
    {

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.ContentType = "application/json";
        request.Method = "GET";

        Task<WebResponse> task = Task.Factory.FromAsync (request.BeginGetResponse, asyncResult => request.EndGetResponse (asyncResult), (object)null);
        return task.ContinueWith (t => ReadStreamFromResponse (t.Result));

    }
    private string ReadStreamFromResponse(WebResponse response)
    {
        using (Stream responseStream = response.GetResponseStream ())
        using (StreamReader sr = new StreamReader (responseStream)) {
            string strContent = sr.ReadToEnd ();
            return strContent;
        }
    }

    public string getRawResponse(){
        var task = StartWebRequest(string.Format (@"https://pawprints.rit.edu/v1/petitions?key={0}&limit={1}", "apikey", 50));

        this.response = task.Result;
        return response;
    }
}


public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
    protected override void OnCreate (Bundle bundle)
    {
        ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback((sender, certificate, chain, policyErrors) => { return true; });

        base.OnCreate (bundle);

        global::Xamarin.Forms.Forms.Init (this, bundle);

        LoadApplication (new App ());
    }
}
static void Main (string[] args)
    {
        ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback((sender, certificate, chain, policyErrors) => { return true; });
        // if you want to use a different Application Delegate class from "AppDelegate"
        // you can specify it here.
        UIApplication.Main (args, null, "AppDelegate");
        //ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

    }

在我的研究中,我发现了Xamarin bugzilla上的一个错误,该错误可能与之相关,但是我不确定该错误是否适用于我正在使用的版本.我对Xamarin开发人员非常陌生,所以我不熟悉包含哪个版本的Mono.security. https://bugzilla.xamarin.com/show_bug.cgi?id=26658

In my research, I discovered a bug on the Xamarin bugzilla that may be relevant, but I'm not sure that it applies to the version I'm using. I'm very new to Xamarin dev, so I'm not familiar with things like which version of Mono.security is included. https://bugzilla.xamarin.com/show_bug.cgi?id=26658

如果有帮助,这是该异常的相关部分:

If it's helpful, here is the relevant portion of the exception:

System.AggregateException: One or more errors occurred ---> System.Exception: One or more errors occurred ---> System.Exception: Error: SendFailure (Error writing headers) ---> System.Exception: Error writing headers ---> System.Exception: The authentication or decryption has failed. ---> System.Exception: The authentication or decryption has failed.


at Mono.Security.Protocol.Tls.RecordProtocol.ProcessAlert (AlertLevel alertLevel, AlertDescription alertDesc) [0x00013] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.6.1.26/src/mono/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs:654
at Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback (IAsyncResult asyncResult) [0x000dc] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.6.1.26/src/mono/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs:377

推荐答案

您正在访问pawprints.rit.edu对吗?

然后该站点的证书(以及它的根CA)就可以了,即iOS会接受它(而Xamarin.iOS将信任决定委托给iOS). IOW设置委托对您没有帮助(仅用于证书,可以).

Then the certificate for the site (and it's root CA) are fine, i.e. iOS would accept it (and Xamarin.iOS delegate the trust decision to iOS). IOW setting the delegate does not help you (it's for the certificate only and that's fine).

这里的问题是服务器已已配置仅允许TLS 1.0密码套件的一小部分.它们都不与HttpWebRequest使用的Mono当前的SSL/TLS实现兼容.

The issue here is that the server is configured to allow only a small subset of TLS 1.0 cipher suites. None of them compatible with Mono's current SSL/TLS implementation used by HttpWebRequest.

您最好的选择是使用HttpClientCFNetworkHandler(对于iOS)或第3方句柄(例如,ModernHttpClient适用于iOS和Android).它将使用本机(来自操作系统)的SSL/TLS实现,该实现支持那些密码套件(并且性能要好得多).

Your best alternative is to use a HttpClient and the CFNetworkHandler (for iOS) or a 3rd party handle (e.g. ModernHttpClient would work for both iOS and Android). That will use the native (from the OS) SSL/TLS implementation which has support for those cipher suites (and much better performance).

这篇关于尽管servicePointManager受到黑客攻击,但WebRequest不能在Xamarin.Forms上与ssl一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆