你能强制HttpClient只信任单一证书吗?
...
基本上我想确保客户端只与我的服务器/证书通信。
可以。但是是什么类型的证书?服务器还是CA?下面分别给出了两个示例。
此外,在服务器的情况下,固定公钥可能比固定证书更好。这是因为一些组织(如Google)每30天左右会轮换其服务器证书,以使移动客户端的CRL保持较小。然而,这些组织将重新认证相同的公钥。
这是一个关于从
使用特定CA建立SSL连接中固定CA的示例。它
不需要将证书放置在证书存储中。你可以将CA嵌入到你的应用程序中。
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);
chain2.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
chain2.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain2.Build(new X509Certificate2(certificate));
if (chain2.ChainStatus.Length == 0)
return false;
bool result = chain2.ChainStatus[0].Status == X509ChainStatusFlags.NoError;
Debug.Assert(result == true);
return result;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
return false;
}
我还没有找到如何默认使用此链(上面的
chain2
)而无需回调的方法。也就是说,将其安装在ssl套接字上,连接将“自动工作”。
我还没有弄清楚如何安装它,使其传递到回调函数中。也就是说,每次调用回调时都必须构建该链,因为我的
chain2
未作为
chain
传递给函数。
这是一个关于OWASP的
证书和公钥固定的服务器证书固定示例。它不需要将证书放置在证书存储中。您可以在应用程序中携带证书或公钥。
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;
return false;
}