I have an certificate which I can read using the X509Certificate2 class like this:
X509Certificate2 certificate = new X509Certificate2(@"certificate.pem");
But I also have an EC private key. 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?
This is the rest of my code:
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With