xamarin.android 添加客户端证书 [英] xamarin.android adding client certificate

查看:25
本文介绍了xamarin.android 添加客户端证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试向 Xamarin.Android 中的 Web api 发送请求.api 需要客户端证书.我遵循了这个问题中的建议:xamarin.ios httpclient clientcertificate not working withhttps,但出现方法未实现"异常.有人可以帮忙吗?

I'm trying to send a request to a web api in Xamarin.Android. The api requires a client certificate. I followed the advice in this question: xamarin.ios httpclient clientcertificate not working with https, but I get a "method not implemented" exception. Can anyone help?

这是我的代码:

    string result = await CallApi(new System.Uri("myurl"));

    protected async Task<string> CallApi(Uri url)
    {
        try
        {
            AndroidClientHandler clientHandler = new AndroidClientHandler();
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Ssl3;

            using (var mmstream = new MemoryStream())
            {
                Application.Context.Assets.Open("mycert.pfx").CopyTo(mmstream);
                byte[] b = mmstream.ToArray();

                X509Certificate2 cert = new X509Certificate2(b, "password", X509KeyStorageFlags.DefaultKeySet);
                clientHandler.ClientCertificates.Add(cert);
            }

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

            HttpClient client = new HttpClient(clientHandler);
            HttpResponseMessage response = await client.GetAsync(url);
            response.EnsureSuccessStatusCode();

            string responseBody = await response.Content.ReadAsStringAsync();
            Console.WriteLine(responseBody);
            return responseBody;
        }
        catch (HttpRequestException e)
        {
            Console.WriteLine("
Exception Caught!");
            return string.Empty;
        }
    }

推荐答案

在您提到的帖子中,可能使用了托管处理程序.由于此处理程序当前不支持 TLS 1.2,因此您不应使用它,而是真正使用 AndroidClientHandler(另请参阅 Xamarin 和 TLS 1.2).不幸的是 ClientCertificates 确实没有在 AndroidClientHandler 中实现.

In the post you mentioned probably the managed handler is used. Since this handler currently doesn't support TLS 1.2 you shouldn't use it, but instead really use the AndroidClientHandler (see also Xamarin and TLS 1.2). Unfortunately ClientCertificates is indeed not implemented in AndroidClientHandler.

如果你想在android中使用客户端证书,你可以扩展AndroidClientHandler:

If you want to use client certificate with android you can extend the AndroidClientHandler:

using Java.Security;
using Java.Security.Cert;
using Javax.Net.Ssl;
using Xamarin.Android.Net; 
using Xamarin.Forms;

public class AndroidHttpsClientHandler : AndroidClientHandler
{
    private SSLContext sslContext;

    public AndroidHttpsClientHandler(byte[] customCA, byte[] keystoreRaw) : base()
    {
        IKeyManager[] keyManagers = null;
        ITrustManager[] trustManagers = null;

        // client certificate
        if (keystoreRaw != null)
        {
            using (MemoryStream memoryStream = new MemoryStream(keystoreRaw))
            {
                KeyStore keyStore = KeyStore.GetInstance("pkcs12");
                keyStore.Load(memoryStream, clientCertPassword.ToCharArray());
                KeyManagerFactory kmf = KeyManagerFactory.GetInstance("x509");
                kmf.Init(keyStore, clientCertPassword.ToCharArray());
                keyManagers = kmf.GetKeyManagers();
            }
        }

        // custom truststore if you have your own ca
        if (customCA != null)
        {
            CertificateFactory certFactory = CertificateFactory.GetInstance("X.509");

            using (MemoryStream memoryStream = new MemoryStream(customCA))
            {
                KeyStore keyStore = KeyStore.GetInstance("pkcs12");
                keyStore.Load(null, null);
                keyStore.SetCertificateEntry("MyCA", certFactory.GenerateCertificate(memoryStream));
                TrustManagerFactory tmf = TrustManagerFactory.GetInstance("x509");
                tmf.Init(keyStore);
                trustManagers = tmf.GetTrustManagers();
            }
        }
        sslContext = SSLContext.GetInstance("TLS");
        sslContext.Init(keyManagers, trustManagers, null);
    }

    protected override SSLSocketFactory ConfigureCustomSSLSocketFactory(HttpsURLConnection connection)
    {
        SSLSocketFactory socketFactory = sslContext.SocketFactory;
        if (connection != null)
        {
            connection.SSLSocketFactory = socketFactory;
        }
        return socketFactory;
    }
}

这篇关于xamarin.android 添加客户端证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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