Können Sie Httpclient zwingen, nur ein einziges Zertifikat vertrauen? ... Grundsätzlich möchte ich sicherstellen, dass es nur mein Server/Zertifikat sein kann, mit dem mein Client spricht.
Ja. Aber welche Art von Zertifikat? Server oder CA? Beispiele für beide folgen.
Es könnte auch besser sein, den öffentlichen Schlüssel als das Zertifikat im Falle eines Servers zu pinnen. Das liegt daran, dass einige Organisationen wie Google ihre Serverzertifikate alle 30 Tage oder so drehen, um die CRLs für mobile Clients klein zu halten. Die Organisationen werden jedoch den öffentlichen Schlüssel denselben erneut zertifizieren.
Hier ist ein Beispiel für die CA von Use a particular CA for a SSL connection Pinning. Es erfordert nicht, das Zertifikat in einem Zertifikatspeicher zu platzieren. Sie können die CA in Ihrer App herumtragen.
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;
}
Ich habe nicht herausgefunden, wie diese Kette zu verwenden (chain2
oben) standardmäßig, so dass es für den Rückruf nicht erforderlich ist. Das heißt, installieren Sie es auf dem SSL-Socket und die Verbindung wird "einfach funktionieren".
Und ich habe nicht herausgefunden, wie es installieren, so dass es in den Rückruf übergeben. Das heißt, ich muss die Kette für jeden Aufruf des Rückrufs erstellen, da meine chain2
nicht in die Funktionen wie chain
übergeben wird.
Hier ist ein Beispiel von Certificate and Public Key Pinning das Server-Zertifikat von OWASP des Pinning. Es erfordert nicht, das Zertifikat in einem Zertifikatspeicher zu platzieren. Sie können das Zertifikat oder den öffentlichen Schlüssel in Ihrer App mit sich herumtragen.
// 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;
}
Gute Frage. Es ist großartig zu sehen, dass Sie proaktive Maßnahmen ergreifen, um den Kanal zu härten. – jww