Associate a private key with the X509Certificate2 class in .net
For everyone else with the same problem, I found a neat little piece of code that let's you do exactly that:
http://www.codeproject.com/Articles/162194/Certificates-to-DB-and-Back
byte[] certBuffer = Helpers.GetBytesFromPEM(publicCert, PemStringType.Certificate);
byte[] keyBuffer = Helpers.GetBytesFromPEM(privateKey, PemStringType.RsaPrivateKey);
X509Certificate2 certificate = new X509Certificate2(certBuffer, password);
RSACryptoServiceProvider prov = Crypto.DecodeRsaPrivateKey(keyBuffer);
certificate.PrivateKey = prov;
EDIT: The code for the Helper method (which otherwise requires a codeproject login) is as follows:
public static byte[] GetBytesFromPEM(string pemString, PemStringType type)
{
string header; string footer;
switch (type)
{
case PemStringType.Certificate:
header = "-----BEGIN CERTIFICATE-----";
footer = "-----END CERTIFICATE-----";
break;
case PemStringType.RsaPrivateKey:
header = "-----BEGIN RSA PRIVATE KEY-----";
footer = "-----END RSA PRIVATE KEY-----";
break;
default:
return null;
}
int start = pemString.IndexOf(header) + header.Length;
int end = pemString.IndexOf(footer, start) - start;
return Convert.FromBase64String(pemString.Substring(start, end));
}
Update
As of .NET 5 you can simply use CreateFromPem(ReadOnlySpan, ReadOnlySpan):
Creates a new X509 certificate from the contents of an RFC 7468 PEM-encoded certificate and private key.
example:
X509Certificate2 cert = X509Certificate2.CreateFromPem(
certPem, //The text of the PEM-encoded X509 certificate.
keyPem //The text of the PEM-encoded private key.
);
Or if you have a string with both the cert and its private key, you can pass it in for both the cert arg and the key arg:
X509Certificate2 cert = X509Certificate2.CreateFromPem(
certPem, //The text of the PEM-encoded X509 certificate.
certPem// The text of the PEM-encoded private key.
);
You can save yourself the hassle of copy-pasting all that code and store the private key next to the certificate in a pfx
/pkcs#12
file:
openssl pkcs12 -export -in my.cer -inkey my.key -out mycert.pfx
You'll have to supply a password, which you have to pass to the constructor of X509Certificate2
:
X509Certificate2 cert = new X509Certificate2("mycert.pfx","password");