我試圖對需要雙向SSL連接(客戶端身份驗證)的服務器進行HTTP調用。我有一個包含多個證書和密碼的.p12文件。請求使用協議緩衝區序列化。HTTPClient的雙向身份驗證
我的第一個想法是將密鑰庫添加到HttpClient使用的WebRequestHandler的ClientCertificate屬性中。我還將密鑰庫添加到我的計算機上受信任的根證書頒發機構。
當PostAsync執行時,我總是收到「無法創建ssl/tls安全通道」。顯然有些事我做錯了,但我在這裏有點失落。
任何指針,將不勝感激。
public void SendRequest()
{
try
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
var handler = new WebRequestHandler();
// Certificate is located in bin/debug folder
var certificate = new X509Certificate2Collection();
certificate.Import("MY_KEYSTORE.p12", "PASSWORD", X509KeyStorageFlags.DefaultKeySet);
handler.ClientCertificates.AddRange(certificate);
handler.ServerCertificateValidationCallback = ValidateServerCertificate;
var client = new HttpClient(handler)
{
BaseAddress = new Uri("SERVER_URL")
};
client.DefaultRequestHeaders.Add("Accept", "application/x-protobuf");
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/x-protobuf");
client.Timeout = new TimeSpan(0, 5, 0);
// Serialize protocol buffer payload
byte[] protoRequest;
using (var ms = new MemoryStream())
{
Serializer.Serialize(ms, MyPayloadObject());
protoRequest = ms.ToArray();
}
var result = await client.PostAsync("/resource", new ByteArrayContent(protoRequest));
if (!result.IsSuccessStatusCode)
{
var stringContent = result.Content.ReadAsStringAsync().Result;
if (stringContent != null)
{
Console.WriteLine("Request Content: " + stringContent);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
// Do not allow this client to communicate with unauthenticated servers.
return false;
}
編輯
我甚至不闖入ValidateServerCertificate。一旦PostAsync被調用,拋出異常。協議絕對是TLS v1。
客戶端操作系統是Windows 8.1。服務器是用Java編碼(不知道是什麼操作系統運行它的。我沒有訪問它。這是一個黑盒子。)
堆棧跟蹤
在System.Net.HttpWebRequest.EndGetRequestStream( IAsyncResult的asyncResult,TransportContext &上下文) 在System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult的AR)
有沒有內部異常。
誰是存儲在.P12文件中的證書的頒發者?服務器是否信任此類發行人? –
它由我嘗試連接的服務器的所有者發出(他們給我的文件)。 – Mathieu
ValidateServerCertificate返回「true」還是「false」?你可以把一個斷點和檢查?如果它返回false,那麼sslPolocyErrors的值是什麼?試着總是從方法中返回'true'來測試這是否解決了這個問題?也許你的本地機器不信任服務器證書的頒發者? –