I'm working on some code that creates a X509certificate and a public/private key pair. The public key is added to the certificate and it is sent to an CA which signs it.
The returned certificate is then accessed through the System.Security.Cryptography.X509Certificates.X509Certificate2 class. Now I want to use this certificate to initiate a secure connection with other clients. Therefore I use the SslStream class. To start the SSL Handshake I use this method:
server.AssociatedSslStream.AuthenticateAsServer( MyCertificate, // Client Certificate true, // Require Certificate from connecting Peer SslProtocols.Tls, // Use TLS 1.0 false // check Certificate revocation );
This method requires that the private key is associated with the certificate. Of course the certificate returned by the CA does not contain a private key. But it is stored as .key file on the harddrive. The X509Certificate2 class has a property called PrivateKey which I guess will associate a private key with the certificate, but I can't find a way to set this property.
Is there any way I can associate the private key with the .net X509 class?
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");
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)); }
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