Search code examples
c#.net-corecertificategrpcx509certificate2

.net core get certificate private key to work with GRPC


I create a self sign certificate. Later I create a google GRPC server who needs a certificate and key file. I try to get the infos from a loaded .net certificate. I get the cert but I have problems with the key file. I dont get the correct key format from the stored cert.

That is only a shot example. Normally I want to store the cert in at the .net cert store and when the grpc service ic created I want to read the cert and key from the store. With that I will instantiate the service.

Cert creation:

 openssl req -newkey rsa:4096 -x509 -sha256 -days 3650 -nodes -out myCert.crt -keyout myCert.key -config cert.conf
 openssl pkcs12 -export -in myCert.crt -inkey myCert.key -out myCert.pfx -passin pass: -passout pass:

Then I load the cert as a .net certificate (normally I will get it from the store):

var cert = new X509Certificate2("myCert.pfx", "", X509KeyStorageFlags.Exportable);
// some stringbuild before to add -----BEGIN PRIVATE KEY-----
var privateKeyFromDotNetCert = Convert.ToBase64String(x509Certificate2.GetRSAPrivateKey().ExportRSAPrivateKey());
// for reference read the original key..only to shwo the problem
var serverkey = File.ReadAllText("myCert.key");

privateKeyFromDotNetCert is different to the original server key.

later I try to

  var keypair = new KeyCertificatePair(cacert, serverkey);
  var sslCredentials = new SslServerCredentials(new List<KeyCertificatePair> { keypair }, cacert, false);

with serverKey it works fine but not with the extracted key from the .net certificate. Is it possible to get the correct key from the .net certificate?

Cert creation from .net cert

With the first answer I tried:

  StringBuilder builder = new StringBuilder();
  builder.Append("-----BEGIN PRIVATE KEY-----");
  builder.AppendLine(Convert.ToBase64String(certificate.GetRSAPrivateKey().ExportPkcs8PrivateKey(),Base64FormattingOptions.InsertLineBreaks));
  builder.Append("-----END PRIVATE KEY-----");

  privateKeyFromDotNetCert = builder.ToString();

This was working. privateKeyFromDotNetCert is not equal to serverkey. But accepted from the grpc service.


Solution

  • Your comment says you're prepending -----BEGIN PRIVATE KEY----- (and presumably appending -----END PRIVATE KEY-----), but the export method you chose (ExportRSAPrivateKey) doesn't match that format. Try ExportPkcs8PrivateKey, which exports in the PKCS#8 PrivateKeyInfo format, which matches the -----BEGIN PRIVATE KEY----- header. (ExportRSAPrivateKey produces a PKCS#1 RSAPrivateKey, which is -----BEGIN RSA PRIVATE KEY-----.)

    You probably also want to use the Base64FormattingOptions.InsertLineBreaks option.