【问题标题】:How to pass .crt and .key file with httpclient .Net Core Console Application如何使用 httpclient .Net Core Console 应用程序传递 .crt 和 .key 文件
【发布时间】:2022-07-05 20:52:44
【问题描述】:

我正在与hashicorp 建立联系。我们需要在 .net 中调用解密 api。要调用解密 API,我们需要在其中传递令牌。 但是令牌调用不同,它使用客户端证书和密钥进行身份验证。我们正在从 .net 应用程序调用令牌生成 url,但收到错误 ""{"errors":["client certificate must be provided"]}\n""。

var allKeyytes =  File.ReadAllBytes(@"file.key");
        var privateKey = new X509Certificate2(allKeyytes, "XXXXXX").PrivateKey as DSACryptoServiceProvider;
        var certificate2 = new X509Certificate2(@"file.crt");
        certificate2.CopyWithPrivateKey(privateKey);
        HttpClientHandler handler = new HttpClientHandler();
        handler.ClientCertificates.Add(certificate2);

        using (HttpClient client = new HttpClient(handler))
        {
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, vaultUrl);
            HttpResponseMessage response = client.SendAsync(request).Result;

            if (response.IsSuccessStatusCode)
            {
                var result = response.Content.ReadAsStringAsync().Result;

            }
        }

添加上述代码行后出现错误“System.Security.Cryptography.CryptographicException: '找不到请求的对象。”

请让我知道我做错了什么!

提前谢谢你。

【问题讨论】:

  • certificate2.CopyWithPrivateKey(provider); 你没有使用结果。同样缺少usingprovider certificate2 requestresponse。而且调用.Result很可能会造成死锁,改用await

标签: c# .net .net-core console-application


【解决方案1】:

代码不正确。在第 2 行,您正在读取第一个参数中的私钥,它应该是包含私钥的加密证书。此外,此方法已过时。

我做了下面的代码,它运行成功。如果您使用的是 DSA,则可以将 RSA 替换为 DSA

using System.Text;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

int bytesread;
var allKeyytes = File.ReadAllBytes(@"tls.key");
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
provider.ImportFromPem(File.ReadAllText("tls.key"));
var certificate2 = new X509Certificate2(@"tls.cer");
certificate2.CopyWithPrivateKey(provider);
HttpClientHandler handler = new HttpClientHandler();
handler.ClientCertificates.Add(certificate2);

using (HttpClient client = new HttpClient(handler))
{
    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://www.google.com");
    HttpResponseMessage response = client.SendAsync(request).Result;

    if (response.IsSuccessStatusCode)
    {
        var result = response.Content.ReadAsStringAsync().Result;

    }
}

【讨论】:

  • 感谢您的回复。使用您的代码时,我收到语法错误,提示“RSACryptoServiceProvider”不包含 ImportFromPem。还有一件事,我们有 passPhrase 作为密钥,所以请让我知道谁也可以通过它。 TIA。
【解决方案2】:

您实际上并没有使用返回新证书的CopyWithPrivateKey 的结果,它不会修改原始证书。

你在各种对象上也缺少using,你还需要使用await而不是.Result,否则你可能会死锁

var allKeyytes =  File.ReadAllBytes(@"file.key");
using (var crt = new X509Certificate2(@"file.crt"))
using (var privateKey = new X509Certificate2(allKeyytes, "XXXXXX"))
using (var certificate2 = crt.CopyWithPrivateKey(privateKey.GetDSAPrivateKey()))
{
    HttpClientHandler handler = new HttpClientHandler();
    handler.ClientCertificates.Add(certificate2);

    using (var client = new HttpClient(handler))
    using (var request = new HttpRequestMessage(HttpMethod.Post, vaultUrl))
    {
        using (var response = client.SendAsync(request))
        {
            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsStringAsync();

            }
        }
    }
}

如果私钥实际上是 RSA,那么您需要转换为 privateKey.GetRSAPrivateKey()

理想情况下,HttpClient 将缓存在一个静态的 .为此,您只会处理 crtprivateKey 而不是 certificate2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 2020-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    相关资源
    最近更新 更多