强制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;
}