android - Xamarin AndroidClientHandler 发送客户端证书

标签 android ssl xamarin httpclient client-certificates

我想我可能在这里遗漏了一些东西,但是如何将客户端证书发送到需要客户端证书的 SSL 站点。

我正在使用 HttpClient 并传递一个 AndroidClientHandler

有很多答案提供了代码,但没有告诉我为什么代码有效或何时应该调用它。我在这上面花了一个多星期。

有人可以提供一个简单的代码示例并简单解释为什么应该这样做。

我正在使用自签名证书。我设法忽略了任何证书验证,并且可以在配置为不需要客户端证书时调用 SSL 站点。

但现在我需要知道如何通过客户端证书。

我查看了许多文章和解决方案,但没有看到客户端证书在哪里通过。

任何帮助,将不胜感激。谢谢

最佳答案

我见过的 Xamarin 示例没有将 IPrivateKey 添加到用于填充 KeyManagerFactory 的 KeyStore

/// <summary>
/// Represents a Java X509Certificate with private key
/// </summary>
public class CertificateDetails
{
    public CertificateDetails(IPrivateKey privateKey, X509Certificate[] chain)
    {
        PrivateKey = privateKey;
        Chain = chain;
    }

    /// <summary>
    /// Gets the private key
    /// </summary>
    public IPrivateKey PrivateKey { get; }

    /// <summary>
    /// Gets certificate chain
    /// </summary>
    public IReadOnlyCollection<X509Certificate> Chain { get; }
}


/// <summary>
/// HttpClientHandler based on native Android  <see cref="Java.Net.HttpURLConnection"/> that uses a client certificate
/// </summary>
public class AuthAndroidClientHander : AndroidClientHandler
{
    readonly CertificateDetails _certificateDetails;

    public AuthAndroidClientHander(CertificateDetails certificateDetails)
    {
        if (certificateDetails is null)
        {
            throw new ArgumentNullException(nameof(certificateDetails));
        }
        _certificateDetails = certificateDetails;

        //get root certs
        var trustManagerFactory = TrustManagerFactory.GetInstance(TrustManagerFactory.DefaultAlgorithm);
        trustManagerFactory.Init((KeyStore)null);
        var x509trustManager = trustManagerFactory.GetTrustManagers().OfType<IX509TrustManager>().First();
        var acceptedIssuers = x509trustManager.GetAcceptedIssuers();

        //trust both default issuers and chain of client certifiate
        TrustedCerts = _certificateDetails.Chain.Concat(acceptedIssuers).ToList<Certificate>();
    }

    /// <summary>
    /// Configure keyStore passed into <see cref="AndroidClientHandler.ConfigureKeyManagerFactory"/> and <see cref="AndroidClientHandler.ConfigureTrustManagerFactory"/>
    /// </summary>
    /// <param name="keyStore"></param>
    /// <returns></returns>
    protected override KeyStore ConfigureKeyStore(KeyStore keyStore)
    {
        // replace keyStore generated by base class with a PKCS12 instead of the default KeyStore.DefaultType
        keyStore = KeyStore.GetInstance("PKCS12");

        //replicate base's SetupSSL() behavior of adding all TrustedCerts to keystore in  
        keyStore.Load(null, null);

        if (TrustedCerts?.Any() == true)
        {

            for (var i = 0; i < TrustedCerts.Count; i++)
            {

                Certificate cert = TrustedCerts[i];
                if (cert == null)
                {
                    continue;
                }
                keyStore.SetCertificateEntry($"ca{i}", cert);

            }

        }

        //add private key to keystore
        keyStore.SetKeyEntry("privateKey", _certificateDetails.PrivateKey, null, _certificateDetails.Chain.ToArray());

        return keyStore;
    }

    protected override KeyManagerFactory ConfigureKeyManagerFactory(KeyStore keyStore)
    {
        var kmf = KeyManagerFactory.GetInstance("x509");
        kmf.Init(keyStore, null);
        return kmf;
    }

    protected override TrustManagerFactory ConfigureTrustManagerFactory(KeyStore keyStore)
    {
        var tmf = TrustManagerFactory.GetInstance(TrustManagerFactory.DefaultAlgorithm);
        tmf.Init(keyStore);
        return tmf;
    }
}

关于android - Xamarin AndroidClientHandler 发送客户端证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53547060/

相关文章:

java - Android:如何使用自签名证书和 SSL 缓存创建 HttpClient

xamarin - 如何在xamarin表单中创建复选框

ssl - 为 Elastic Beanstalk 配置 SSL

amazon-web-services - ssl 证书更新并重新导入到 aws

android - 如何在 Android 中识别音调?

android - 使用 ffmpeg 确定歌曲的节奏

ios - 使用 lldb 通过 Xamarin 调试 native 库

c# - 加载程序集 Xamarin.Android.Support.v4 时出现异常

android - 抽屉导航项目中未找到资源异常

android - Android 可以接收 IOS 蓝牙信号吗