简体   繁体   English

为证书提供 EC 私钥以供在 HttpClient 中使用 C#

[英]Providing an EC private key to certificate for use in HttpClient C#

I have an certificate which I can read using the X509Certificate2 class like this:我有一个证书,可以使用 X509Certificate2 class 读取,如下所示:

X509Certificate2 certificate = new X509Certificate2(@"certificate.pem"); X509Certificate2 证书 = new X509Certificate2(@"certificate.pem");

But I also have an EC private key.但我也有一个EC私钥。 This are it's file contents.这是它的文件内容。

-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIKpAuZ/Wwp7FTSCNJ56fFM4Y/rf8ltXp3xnrooPxNc1UoAoGCCqGSM49
AwEHoUQDQgAEqiRaEw3ItPsRAqdDjJCyqxhfm8y3tVrxLBAGhPM0pVhHuqmPoQFA
zR5FA3IJZaWcopieEX5uZ4KMtDhLFu/FHw==
-----END EC PRIVATE KEY-----

How do I 'feed' this private key to the certificate and eventually to my HttpClient so that it will become usable as a client certificate?我如何将这个私钥“提供”给证书并最终提供给我的HttpClient ,以便它可以用作客户端证书?

This is the rest of my code:这是我的代码的 rest:

X509Certificate2 certificate = new X509Certificate2(@"certificate.pem");
//certificate.PrivateKey = something;
httpClientHandler.ClientCertificates.Clear();
httpClientHandler.ClientCertificates.Add(certificate);
httpClientHandler.SslProtocols = SslProtocols.Tls12;
httpClientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;

HttpClient httpClient = new HttpClient(httpClientHandler);
HttpResponseMessage result = httpClient.GetAsync("https://server.cryptomix.com/secure/").Result;
string str = result.Content.ReadAsStringAsync().Result;

I think I've got it... This uses the BouncyCastle NuGet package. 我想我已经明白了...它使用BouncyCastle NuGet包。

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using System.Security.Cryptography.X509Certificates;
using System;
using System.IO;

string pemKey = @"-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIKpAuZ/Wwp7FTSCNJ56fFM4Y/rf8ltXp3xnrooPxNc1UoAoGCCqGSM49
AwEHoUQDQgAEqiRaEw3ItPsRAqdDjJCyqxhfm8y3tVrxLBAGhPM0pVhHuqmPoQFA
zR5FA3IJZaWcopieEX5uZ4KMtDhLFu/FHw==
-----END EC PRIVATE KEY-----";

string pemCert = @"-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----";

var keyPair = (AsymmetricCipherKeyPair)new PemReader(new StringReader(pemKey)).ReadObject();
var cert = (Org.BouncyCastle.X509.X509Certificate)new PemReader(new StringReader(pemCert)).ReadObject();

var builder = new Pkcs12StoreBuilder();
builder.SetUseDerEncoding(true);
var store = builder.Build();

var certEntry = new X509CertificateEntry(cert);
store.SetCertificateEntry("", certEntry);
store.SetKeyEntry("", new AsymmetricKeyEntry(keyPair.Private), new[] { certEntry });

byte[] data;
using (var ms = new MemoryStream())
{
    store.Save(ms, Array.Empty<char>(), new SecureRandom());
    data = ms.ToArray();
}

var x509Cert = new X509Certificate2(data);

The trick seems to be to combine the cert and key together into a pkcs12 container, then feed that into X509Certificate2 in one go. 诀窍似乎是将证书和密钥组合到一个pkcs12容器中,然后一次性将其馈入X509Certificate2

Combining the certificate and key with openssl, and feeding that into the x509certificate class works: 将证书和密钥与openssl组合在一起,并将其馈送到x509certificate类中可以工作:

openssl pkcs12 -export -in certificate.pem -inkey privatekey.pem -out cert-and-key.pfx

And then using this to obtain a class with assigned private key: 然后使用它来获得具有分配的私钥的类:

X509Certificate2 certificate = new X509Certificate2("cert-and-key.pfx", "password");

And then the code in my question works. 然后我的问题中的代码起作用。

You can simply use the X509Certificate2.CreateFromPemFile method您可以简单地使用 X509Certificate2.CreateFromPemFile 方法

var httpClientHandler = new HttpClientHandler();
var cert = X509Certificate2.CreateFromPemFile(certificateFile, privateKeyFile);
httpClientHandler.ClientCertificates.Add(cert);
var httpClient = new HttpClient(httpClientHandler);
HttpResponseMessage result = httpClient.GetAsync("https://server.cryptomix.com/secure/").Result;
string str = result.Content.ReadAsStringAsync().Result;

where certificateFile and privateKeyFile are file paths to your PEM files,其中 certificateFile 和 privateKeyFile 是 PEM 文件的文件路径,

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C#,. Net核心私钥认证httpClient - C#, .Net Core Private key authentication httpClient 如何在 C#/Xamarin 中使用带有来自 android 钥匙串的私钥的 X.509 证书? - How can I use an X.509 certificate with private key from the android keychain in C#/Xamarin? C# SSL 服务器模式必须使用带有相应私钥的证书 - C# SSL server mode must use a certificate with the corresponding private key C# BouncyCastle 使用 PemWriter 导出 EC 私钥 - C# BouncyCastle EC Private Key Export Using PemWriter 将私钥添加到 X509Certificate2 - C# - Adding a private key to X509Certificate2 - C# 在 C# 中将公共证书与私有 RSA 密钥相结合 - Combining Public Certificate with Private RSA Key in C# 在 android/iOS Keystore C# 上存储私钥和证书 (.pem) - Storing private key and certificate (.pem) on android/iOS Keystore C# 在 C# 中以编程方式将证书和私钥转换为 .PFX - Convert Certificate and Private Key to .PFX programmatically in C# C#解密与X.509证书没有私钥 - C# Decryption with X.509 certificate without private key HttpWebRequest - C# - 使用 Certificate.crt + private.key 发布 - HttpWebRequest - C# - Post with Certificate.crt + private.key
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM