【发布时间】:2019-06-06 14:55:34
【问题描述】:
我们的朋友在将私有证书加载到 httpHandler 时遇到问题。
我们正在使用 .net 核心,需要在云中托管所有应用程序。
主要目标是从 SQS 获取消息并在使用数据后执行一些指定的 API 拍摄。
我们的公钥/私钥证书有问题。我们已经尝试了所有可能的加载方式。
public async Task<HttpResponseMessage> VisitHttps()
{
// Proceed for an invalid cerficate
ServicePointManager.ServerCertificateValidationCallback +=
(sender, certificate, chain, sslPolicyErrors) => true;
// Add the certificate
var handler = new HttpClientHandler();
var cert = GetMyCert();
if (cert != null)
{
handler.ClientCertificates.Add(cert);
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
//handler.PreAuthenticate = true;
}
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
HttpClient cclient = new HttpClient(handler)
{
//BaseAddress = new Uri("https://someurl.com")
};
cclient.DefaultRequestHeaders.Accept.Clear();
cclient.DefaultRequestHeaders.Accept.Add(new
MediaTypeWithQualityHeaderValue("application/json"));
return await cclient.GetAsync("https://some-url.com/ping"); }
GetMyCert() 方法如下所示:
string currentLocation = $"{AppDomain.CurrentDomain.BaseDirectory}key-public.crt";
//var xcert = new X509Certificate2(currentLocation, "password");
////var currentLocationPriv = $"{AppDomain.CurrentDomain.BaseDirectory}key-private.crt";
////var privcert = new X509Certificate2(currentLocationPriv, "password", X509KeyStorageFlags.EphemeralKeySet);
//var certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
//certStore.Open(OpenFlags.ReadWrite);
//certStore.Add(xcert);
//certStore.Close();
//return xcert;
X509Store store = new X509Store("My", StoreLocation.CurrentUser);
X509Certificate2 cert;
cert = new X509Certificate2(File.ReadAllBytes(currentLocation), "password", X509KeyStorageFlags.MachineKeySet);
bool result = cert.Verify();
var r2 = result;
return cert;
注释行与我们尝试做的不同。
我们不知道还应该尝试什么来处理这个问题。
任何指导方针都会受到欢迎
编辑:
我已经尝试在启动类中注册它,但它似乎无论如何都不起作用。我总是将证书内的私钥字段为空。并将 hasPrivateKey 标记为 false。
private void CreateCert(IServiceCollection services)
{
string currentLocation = $"{AppDomain.CurrentDomain.BaseDirectory}key-public.crt";
var certificate = new X509Certificate2(currentLocation, "password");
services.AddHttpClient("TestClient", client =>
{
client.BaseAddress = new Uri("https://someurl.com");
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(certificate);
return handler;
});
}
我的测试代码:
[Fact]
public async Task ShouldPong()
{
var testClient = new TestClient()
{
BaseAddress = new Uri("https://someurl.com")
};
var result = await testClient.GetAsync("/ping");
result.StatusCode.Should().Be(HttpStatusCode.OK);
}
测试客户端:
public class TestClient : HttpClient
{
public TestClient()
:base()
{
}
public TestClient(HttpMessageHandler handler)
: base(handler)
{
}
}
编辑:
将 .crt 文件更改为 .pfx 文件时问题已解决。由于我们使用的 API 托管在 nginx 上。
【问题讨论】:
-
.Net Core 提供了一种处理 HttpClient 的新方法,即通过注入 HttpClientFactory。还有命名客户端,即注入到您的模块/类中的预配置客户端。可能,您可以使用这个问题的答案:stackoverflow.com/questions/56480160/…
-
对不起,你已经链接了我自己的问题,我会检查 httpClientFactory :)
-
对不起,我错了哈哈。这是正确的链接:stackoverflow.com/questions/52371768/…
-
好的,谢谢 :) 这没有帮助,顺便说一句,问题可能是当我在调试期间查看句柄时,它显示私钥为空且未设置。我应该用我的公钥以某种方式加载它还是添加它?
标签: c# .net public-key-encryption private-key