11

We use C# code we build X509Certificate2 with .p12 file, in the constructor we insert the path to certificate, certificate's password. We also marked it as Exportable as shown below:

X509Certificate2 x509Certificate2 = new X509Certificate2
("...\\MyCerificate.p12", "P@ssw0rd", X509KeyStorageFlags.Exportable);

we get the private key as AsymmetricAlgorithm format by the following:

x509Certificate2.PrivateKey

Now, we want to get the private key from the certificate as Base64 format - but we don't have any idea how to do it, and its so important for us.

Kiquenet
  • 14,494
  • 35
  • 148
  • 243
RRR
  • 3,937
  • 13
  • 51
  • 75

4 Answers4

6

The important question is why base64 ?

If this is for your own application then you can keep the private key as an XML string (much easier :-).

string xml = x509Certificate2.PrivateKey.ToXmlString (true);

If you want base64 (again just for your application) you can export the key (RSAParameters) then concat every byte[] and turn the merged output to a base64 string.

But if you want to interop with other applications that requires a base64 private key then you need to know the format (inside the base64 string). E.g. in many case private keys are PEM encoded (which is base64 with a special header/footer, see an example for X509Certificate).

If that what's you're looking for then you'll need to encode the private key within a PKCS#8 structure first, then turn in into base64 and add the header/footer. You can find some helpful code to do so inside Mono.Security.dll (MIT.X11 licensed code from the Mono project).

poupou
  • 43,413
  • 6
  • 77
  • 174
  • I depented on other application that requires to get base64 private key. I want to allow the user to insert X509Certificate2 and by myself extract the private key as base 64 format - do you know if .Net framework expose any way to do it? – RRR Oct 11 '11 at 09:49
  • NO, if it did (I really doubt that) or if I knew I would have included it in my answer. That being said your problem remains, it's not a **base64** issue, it's knowing that's **inside** that is important to interop with your other application. – poupou Oct 11 '11 at 12:07
  • The PKCS#8 link seams to be dead, I expected an article there but I only get an overview of RSA Labs' projects – dfsg76 Sep 17 '18 at 10:06
2

You can simply use the PrivateKey property of X509Certificate2. The actual returned private key implementation depends on the algorithm used in the certificate - usually this is RSA:

rsaObj = (RSACryptoServiceProvider)myCertificate.PrivateKey; 

Afterwards you should be able to get the RSA key information from it's ExportParameters property.

Robert
  • 39,162
  • 17
  • 99
  • 152
  • 1
    and when we know thw key information(for example RSA-PKCS1-KeyEx), how can we convert the private key to base64? – RRR Oct 10 '11 at 14:29
-2

You can do that with OpenSSL Library for .NET:

using DidiSoft.OpenSsl;
...
X509Certificate2 x509Certificate2 = new X509Certificate2
("...\\MyCerificate.p12", "P@ssw0rd", X509KeyStorageFlags.Exportable);

PrivateKey privKey = PrivateKey.Load(x509Certificate2.PrivateKey);
bool withNewLines = true;
string base64PrivateKey = privKey.ToBase64String(withNewLines);
-4

If your only problem is to get the private key Base64 encoded, you can simply do like this:

var privateKey = x509Certificate2.PrivateKey;
var encoding = new System.Text.ASCIIEncoding();
var base64String = Convert.ToBase64String(encoding.GetBytes(privateKey.ToString()));
  • 3
    privateKey.ToString() returns the "System.Security.Cryptography.RSACryptoserviceProvider"....., this is not the private key... – RRR Oct 10 '11 at 14:25
  • @RRR is correct. You will find that x509Certificate2.PublicKey.Key.ToString() will return the *same* value doing it this way. That can't be right :) – Matt Borja Jan 09 '14 at 21:27