41

I am trying to export a cert without the private key as as BASE-64 encoded file, same as exporting it from windows. When exported from windows I am able to open the .cer file in notepad.

When I try the following and open on notepad I get binary data...I think it is...not readable.

X509Certificate2 cert = new X509Certificate2("c:\\myCert.pfx", "test", X509KeyStorageFlags.Exportable);

File.WriteAllBytes("c:\\testcer.cer", cert.Export(X509ContentType.Cert));

I tried removing the 'X509KeyStorageFlags.Exportable" but that doesn't work. Am I missing something?

Edit - I tried

File.WriteAllText("c:\\testcer.cer",Convert.ToBase64String(cert.Export(X509ContentType.Cert)))

and that seems to work, however, missing the "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----"

abatishchev
  • 92,232
  • 78
  • 284
  • 421
Saif Khan
  • 17,334
  • 28
  • 97
  • 144
  • Due to outdated mono framework I'm bound to use, I resorted to calling openssl as an external process: `openssl pkcs12 -in importPath -nokeys -passin pass:` - this works on both linux and windows openssl binaries. – Rbjz Jul 22 '16 at 13:10

4 Answers4

71

Perhaps

/// <summary>
/// Export a certificate to a PEM format string
/// </summary>
/// <param name="cert">The certificate to export</param>
/// <returns>A PEM encoded string</returns>
public static string ExportToPEM(X509Certificate cert)
{
    StringBuilder builder = new StringBuilder();            

    builder.AppendLine("-----BEGIN CERTIFICATE-----");
    builder.AppendLine(Convert.ToBase64String(cert.Export(X509ContentType.Cert), Base64FormattingOptions.InsertLineBreaks));
    builder.AppendLine("-----END CERTIFICATE-----");

    return builder.ToString();
}
tyranid
  • 12,552
  • 1
  • 29
  • 32
  • 2
    This method could also be offered as an extension method by placing it into a static class an changing its signature to: `public static string ExportToPEM(this X509Certificate cert)` – cel sharp Sep 21 '15 at 07:12
  • Strangely, `Base64FormattingOptions.InsertLineBreaks` seems to break at column 76, rather than the more [usual 64](https://tools.ietf.org/html/rfc1421)! – Cocowalla Sep 18 '19 at 21:32
7

try this:

X509Certificate2 cerifikata = new X509Certificate2("C://certificate.pfx");
File.WriteAllBytes("D://Test.cer",cerifikata.Export(X509ContentType.Cert));
Tim Cooper
  • 144,163
  • 35
  • 302
  • 261
Arbnor
  • 79
  • 1
  • 1
  • Yeah this will do something like a straight (mostly Windows) DER-encoded binary dump - which works fine w/ most utilities ("certreq", "keytool", "opensSSL", etc). The accepted answer is more standard PEM/ASN.1 format (B-64 string). – galaxis Nov 21 '18 at 23:22
1

For those implementing something similar in .NET Core, here's the code, based on what tyranid did. Base64FormattingOptions.InsertLineBreaks doesn't exist in .NET Core, so I had to implement my own way to do line breaking.

    // Certificates content has 64 characters per lines
    private const int MaxCharactersPerLine = 64;

    /// <summary>
    /// Export a certificate to a PEM format string
    /// </summary>
    /// <param name="cert">The certificate to export</param>
    /// <returns>A PEM encoded string</returns>
    public static string ExportToPem(this X509Certificate2 cert)
    {
        var builder = new StringBuilder();
        var certContentBase64 = Convert.ToBase64String(cert.Export(X509ContentType.Cert));
        // Calculates the max number of lines this certificate will take.
        var certMaxNbrLines = Math.Ceiling((double)certContentBase64.Length / MaxCharactersPerLine);

        builder.AppendLine("-----BEGIN CERTIFICATE-----");
        for (var index = 0; index < certMaxNbrLines; index++)
        {
            var maxSubstringLength = index * MaxCharactersPerLine + MaxCharactersPerLine > certContentBase64.Length
                ? certContentBase64.Length - index * MaxCharactersPerLine
                : MaxCharactersPerLine;
            builder.AppendLine(certContentBase64.Substring(index * MaxCharactersPerLine, maxSubstringLength));
        }
        builder.AppendLine("-----END CERTIFICATE-----");

        return builder.ToString();
    }
David
  • 756
  • 7
  • 20
  • var certContentBase64 = Convert.ToBase64String(cert.Export(X509ContentType.Cert), Base64FormattingOptions.InsertLineBreaks) – prampe Dec 06 '18 at 23:30
0

//however, missing the "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----"

These missing lines are optional. CA may generate them or not depending on settings. For all practical reasons they can be removed from the Base64 encoded file.

Leve
  • 7