我想我可能在这里遗漏了一些东西,但是如何将客户端证书发送到需要客户端证书的SSL站点。
我正在使用HttpClient并传递一个AndroidClientHandler
有许多提供代码的答案,但没有告诉我为什么代码可以工作或何时调用。我已经花了一个多星期了。
有人能提供一个简单的代码示例以及为什么要这样做的简单解释。
我正在使用自签名证书。我设法忽略了任何证书验证,并且在配置为不需要客户端证书时可以调用SSL站点。
但是现在我需要知道如何通过客户端证书。
我看过许多文章和解决方案,但看不到客户证书在哪里传递。
任何帮助将不胜感激。谢谢
答案 0 :(得分:0)
我见过的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;
}
}