Xamarin AndroidClientHandler发送客户端证书
我想我可能遗漏了一些东西,但是如何将客户端证书发送到需要客户端证书的SSL站点呢 我正在使用HttpClient并通过AndroidClientHandler 有很多答案提供了代码,但没有告诉我为什么代码可以工作,或者什么时候应该调用它。我花了一个多星期的时间在这上面 有人能提供一个简单的代码示例和一个简单的解释为什么应该这样做吗 我正在使用自签名证书。我已经设法忽略了任何证书验证,并且可以在配置为不需要客户端证书时调用SSL站点 但是现在我需要知道如何传递客户端证书 我已经看过很多文章和解决方案,但我看不到客户端证书在哪里传递Xamarin AndroidClientHandler发送客户端证书,android,ssl,xamarin,httpclient,client-certificates,Android,Ssl,Xamarin,Httpclient,Client Certificates,我想我可能遗漏了一些东西,但是如何将客户端证书发送到需要客户端证书的SSL站点呢 我正在使用HttpClient并通过AndroidClientHandler 有很多答案提供了代码,但没有告诉我为什么代码可以工作,或者什么时候应该调用它。我花了一个多星期的时间在这上面 有人能提供一个简单的代码示例和一个简单的解释为什么应该这样做吗 我正在使用自签名证书。我已经设法忽略了任何证书验证,并且可以在配置为不需要客户端证书时调用SSL站点 但是现在我需要知道如何传递客户端证书 我已经看过很多文章和解决方
任何帮助都将不胜感激。谢谢我看到的Xamarin示例省略了将IPrivateKey添加到用于填充KeyManagerFactory的密钥库中
/// <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;
}
}
//
///表示具有私钥的Java X509证书
///
公共类证书详细信息
{
公共证书详细信息(IPrivateKey私钥,X509证书[]链)
{
私钥=私钥;
链=链;
}
///
///获取私钥
///
公共IPrivateKey私有密钥{get;}
///
///获取证书链
///
公共IReadOnlyCollection链{get;}
}
///
///HttpClientHandler基于使用客户端证书的本机Android
///
公共类authorIdClientHander:AndroidClientHandler
{
只读认证详细信息\u认证详细信息;
公共授权人和授权人(认证详细信息认证详细信息)
{
如果(CertificatedDetails为空)
{
抛出新ArgumentNullException(nameof(CertificatedDetails));
}
_CertificatedDetails=CertificatedDetails;
//获取根证书
var trustManagerFactory=trustManagerFactory.GetInstance(trustManagerFactory.DefaultAlgorithm);
trustManagerFactory.Init((密钥库)null);
var x509trustManager=trustManagerFactory.GetTrustManagers().OfType().First();
var acceptedIssuers=x509trustManager.GetAcceptedIssuers();
//信任违约发行人和客户认证链
TrustedCerts=_CertificatedDetails.Chain.Concat(acceptedIssuers.ToList();
}
///
///配置传递到和的密钥库
///
///
///
受保护的覆盖密钥库配置密钥库(密钥库密钥库)
{
//将基类生成的密钥库替换为PKCS12,而不是默认的keyStore.DefaultType
keyStore=keyStore.GetInstance(“PKCS12”);
//复制base的SetupSSL()行为,将所有TrustedCert添加到中的密钥库
Load(null,null);
if(TrustedCerts?.Any()==true)
{
对于(var i=0;i
或许可以试试这个博客中的内容:。一般来说,建议不要使用自签名证书,因为CA颁发的官方证书便宜或免费。自签名证书使事情变得复杂。看看这个,它提到了自签名证书。他们谈论的是web应用程序上的SSL证书,还是客户机证书?同样,文章中也不清楚我为什么需要这样做,我想了解这些原则,而不仅仅是将代码复制到我的应用程序中。不幸的是,目前我所拥有的只是自签名证书,因此我陷入了困境。我得出的结论是,您不能使用Xamarin HttpClient和AndroidClientHandler在HTTPS请求中发送客户端证书。有人可以确认吗?我可以确认,如果使用AndroidClientHandler,将永远不会调用System.Net.ServicePointManager.ServerCertificateValidationCallback。如果需要设置并使用该回调,则必须使用托管的HttpClient处理程序。Hi@jgoldberger不太清楚您的意思。这与使用Xamarin HttpClient和AndroidClientHandler在HTTPS请求中发送客户端证书有什么关系这对我来说非常有用。我还能够从用户凭据密钥库添加客户端证书。