如何使用httpclient .net核心控制台应用程序通过.crt和.key文件

发布于 2025-02-12 21:06:10 字数 1089 浏览 0 评论 0原文

我正在与Hashicorp建立联系。我们需要在.NET中调用那里解密API。为了调用解密API,我们需要在其中传递令牌。 但是令牌呼叫不同,它使用客户端证书和键进行身份验证。我们正在从.NET应用程序调用令牌生成URL,但获取错误”“ {“ errors”:[“必须提供客户端证书”]} \ 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:'找不到请求的对象。”

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

先感谢您。

I am working on connection with hashicorp. We need to call there decrypt api in .net. for calling decrypt API, we need to pass token in it.
But token call is different which is using client certificate and key for authentication. We are calling token generation url from .net application but getting error ""{"errors":["client certificate must be supplied"]}\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;

            }
        }

After adding above line of code getting error "System.Security.Cryptography.CryptographicException: 'Cannot find the requested object."

Please let me know what I am doing wrong!

Thank you in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我恋#小黄人 2025-02-19 21:06:10

谢谢大家的帮助。我能够解决这个问题。

它如何解决:
1:使用.crt和.key文件创建PEM文件。
2:使用PFX类型和密码酶导出证书并获得字节数组。
3:使用PFX文件的字节数组创建新证书,然后添加Int HttpClientHandler。
4:在httpclient中传递了clienthandler对象。

using (X509Certificate2 certWithKey = X509Certificate2.CreateFromPemFile(certificateionPath, key))
        {
            byte[] pfxRawData = certWithKey.Export(X509ContentType.Pfx, "123456");

            using (X509Certificate2 pfxCertWithKey = new X509Certificate2(pfxRawData, "123456"))
            {
                HttpClientHandler handler = new HttpClientHandler();
                handler.ClientCertificateOptions = ClientCertificateOption.Manual;
                handler.ServerCertificateCustomValidationCallback = (a, b, c, d) => { return true; };
                handler.ClientCertificates.Add(pfxCertWithKey);

                using (var client = new HttpClient(handler))
                using (var request = new HttpRequestMessage(HttpMethod.Post, vaultUrl))
                {
                    client.DefaultRequestHeaders.Add("X-Vault-Namespace", vaultNamespace);
                    var response = client.SendAsync(request).GetAwaiter().GetResult();
                    var result = response.Content.ReadAsStringAsync();

                }
            }
        }

找到了非常有用的链接: .NET标准 - 将证书和私钥合并到.pfx文件中
这个链接对我有很大帮助!

谢谢大家。

Thank you all for helping. I was able to solve the issue.

How it Solved:
1: Created Pem file using .crt and .key file.
2: Exported the certificate using pfx type and passphrase and got byte array.
3: Created new certificate using byte array of pfx file and Add int HttpClientHandler.
4: Passed clientHandler object in HttpClient.

using (X509Certificate2 certWithKey = X509Certificate2.CreateFromPemFile(certificateionPath, key))
        {
            byte[] pfxRawData = certWithKey.Export(X509ContentType.Pfx, "123456");

            using (X509Certificate2 pfxCertWithKey = new X509Certificate2(pfxRawData, "123456"))
            {
                HttpClientHandler handler = new HttpClientHandler();
                handler.ClientCertificateOptions = ClientCertificateOption.Manual;
                handler.ServerCertificateCustomValidationCallback = (a, b, c, d) => { return true; };
                handler.ClientCertificates.Add(pfxCertWithKey);

                using (var client = new HttpClient(handler))
                using (var request = new HttpRequestMessage(HttpMethod.Post, vaultUrl))
                {
                    client.DefaultRequestHeaders.Add("X-Vault-Namespace", vaultNamespace);
                    var response = client.SendAsync(request).GetAwaiter().GetResult();
                    var result = response.Content.ReadAsStringAsync();

                }
            }
        }

Very useful link found: .NET Standard - Merge a certificate and a private key into a .pfx file programmatically
This link helped me a lot!.

Thank you everyone.

救星 2025-02-19 21:06:10

您不能仅使用私钥创建x509certificate2。您需要使用dsa.importfromencryptedpem读取它。

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

您还缺少在各种对象上使用,您还需要使用等待而不是.result否则,

var allKeyBytes =  File.ReadAllText(@"file.key");
using (var crt = new X509Certificate2(@"file.crt"))
using (var dsa = DSA.Create())
{
    dsa.ImportFromEncryptedPem(allKeyBytes.AsSpan(), "XXXXXX".AsSpan());
    using (var certificate2 = crt.CopyWithPrivateKey(dsa))
    {
        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 = await client.SendAsync(request))
            {
                if (response.IsSuccessStatusCode)
                {
                    var result = await response.Content.ReadAsStringAsync();
                }
            }
        }
    }
}

如果私钥是实际上,RSA然后您需要将施放到rsa.create()等。

理想情况下,httpclient将被静态缓存。为此,您只会处置crtprivateKey不是证书2

You cannot create a X509Certificate2 with just a private key. You need to read it in with DSA.ImportFromEncryptedPem.

You are not actually using the result of CopyWithPrivateKey which returns a new certificate, it does not modify the original.

You are also missing using on various objects, and you also need to use await rather than .Result otherwise you may deadlock

var allKeyBytes =  File.ReadAllText(@"file.key");
using (var crt = new X509Certificate2(@"file.crt"))
using (var dsa = DSA.Create())
{
    dsa.ImportFromEncryptedPem(allKeyBytes.AsSpan(), "XXXXXX".AsSpan());
    using (var certificate2 = crt.CopyWithPrivateKey(dsa))
    {
        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 = await client.SendAsync(request))
            {
                if (response.IsSuccessStatusCode)
                {
                    var result = await response.Content.ReadAsStringAsync();
                }
            }
        }
    }
}

If the private key is actually RSA then you will need to cast to RSA.Create() etc instead.

Ideally the HttpClient would be cached in a static . For that you would only dispose crt and privateKey not certificate2.

╄→承喏 2025-02-19 21:06:10

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

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

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;

    }
}

Code is not right. On line 2, you are reading privatekey in first parameter, it should have been encrypted certificate containing private key. Also, this method is obsolete.

I did the below code and it runs successfully. If you are using DSA, you can replace RSA with 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;

    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文