强制HttpClient信任单个证书 [英] Force HttpClient to trust single Certificate

查看:147
本文介绍了强制HttpClient信任单个证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您可以强制HttpClient仅信任单个证书吗?

Can you force HttpClient to only trust a single certificate?

我知道你可以做到:

WebRequestHandler handler = new WebRequestHandler();
X509Certificate2 certificate = GetMyX509Certificate();
handler.ClientCertificates.Add(certificate);
HttpClient client = new HttpClient(handler);

但是这将迫使它仅信任该单个证书,或者它将信任该证书以及所有fx的证书.GlobalSign可以验证吗?

But will this force it to only trust that single certificate, or will it trust that certifate AND all certificates that fx. GlobalSign can verify?

基本上,我想确保它只能是我的客户端正在与我聊天的服务器/证书.

Basicly I want to ensure that it can ONLY be my server/certificate that my client is talking to.

推荐答案

您可以强制HttpClient仅信任单个证书吗?...基本上,我想确保它只能是我的客户端正在与我聊天的服务器/证书.

Can you force HttpClient to only trust a single certificate? ... Basically I want to ensure that it can ONLY be my server/certificate that my client is talking to.

是的.但是什么类型的证书呢?服务器还是CA?两者的示例如下.

Yes. But what type of certificate? Server or CA? Examples for both follow.

另外,对于服务器,最好固定公钥而不是证书.这是因为某些组织(例如Google)每30天左右轮换一次服务器证书,以使移动客户端的CRL保持较小.但是,组织将重新认证相同公钥.

Also, it might be better to pin the public key rather than the certificate in the case of a server. That's because some organizations, like Google, rotate their server certificates every 30 days or so in an effort to keep the CRLs small for mobile clients. However, the organizations will re-certify the same public key.

这是从将特定CA用于SSL连接.它不需要将证书放置在证书存储中.您可以在应用程序中随身携带CA.

Here's an example of pinning the CA from Use a particular CA for a SSL connection. It does not require placing the certificate in a Certificate Store. You can carry the CA around in your app.

static bool VerifyServerCertificate(object sender, X509Certificate certificate,
    X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    try
    {
        String CA_FILE = "ca-cert.der";
        X509Certificate2 ca = new X509Certificate2(CA_FILE);

        X509Chain chain2 = new X509Chain();
        chain2.ChainPolicy.ExtraStore.Add(ca);

        // Check all properties (NoFlag is correct)
        chain2.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;

        // This setup does not have revocation information
        chain2.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;

        // Build the chain
        chain2.Build(new X509Certificate2(certificate));

        // Are there any failures from building the chain?
        if (chain2.ChainStatus.Length == 0)
            return false;

        // If there is a status, verify the status is NoError
        bool result = chain2.ChainStatus[0].Status == X509ChainStatusFlags.NoError;
        Debug.Assert(result == true);

        return result;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }

    return false;
}

没有弄清楚了默认情况下如何使用此链(上面的 chain2 ),因此不需要回调.也就是说,将其安装在ssl套接字上,连接将正常工作".

I have not figured out how to use this chain (chain2 above) by default such that there's no need for the callback. That is, install it on the ssl socket and the connection will "just work".

没有弄清楚了如何安装它,使其传递到回调中.也就是说,我必须为回调的每次调用构建链,因为我的 chain2 不会作为 chain 传递到函数中.

And I have not figured out how install it such that its passed into the callback. That is, I have to build the chain for each invocation of the callback because my chain2 is not passed into the functions as chain.

这是从OWASP的证书和公钥固定中固定服务器证书的示例.一个>.它不需要将证书放置在证书存储中.您可以在应用程序中随身携带证书或公钥.

Here's an example of pinning the server certificate from OWASP's Certificate and Public Key Pinning. It does not require placing the certificate in a Certificate Store. You can carry the certificate or public key around in your app.

// Encoded RSAPublicKey
private static String PUB_KEY = "30818902818100C4A06B7B52F8D17DC1CCB47362" +
    "C64AB799AAE19E245A7559E9CEEC7D8AA4DF07CB0B21FDFD763C63A313A668FE9D764E" +
    "D913C51A676788DB62AF624F422C2F112C1316922AA5D37823CD9F43D1FC54513D14B2" +
    "9E36991F08A042C42EAAEEE5FE8E2CB10167174A359CEBF6FACC2C9CA933AD403137EE" +
    "2C3F4CBED9460129C72B0203010001";

public static void Main(string[] args)
{
  ServicePointManager.ServerCertificateValidationCallback = PinPublicKey;
  WebRequest wr = WebRequest.Create("https://encrypted.google.com/");
  wr.GetResponse();
}

public static bool PinPublicKey(object sender, X509Certificate certificate, X509Chain chain,
                                SslPolicyErrors sslPolicyErrors)
{
  if (null == certificate)
    return false;

  String pk = certificate.GetPublicKeyString();
  if (pk.Equals(PUB_KEY))
    return true;

  // Bad dog
  return false;
}

这篇关于强制HttpClient信任单个证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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