Skip to content

APIs for exporting certificates and keys to PEM #51630

@vcsjones

Description

@vcsjones

Background and Motivation

In .NET 5, additional APIs were added to make it easier to import public/private keys and certificates that are PEM formatted. Currently there is a lack of making it easier to export PEM formatted cryptographic thingies.

Today, if a developer wanted to do this, they would need to write something like:

X509Certificate2 someCertificate;
string pemContents = new string(PemEncoding.Write("CERTIFICATE", someCertificate.RawData));

While this is just a little bit of code, it is fairly obtuse because it requires the developer to know what PEM label to use. For X.509 certificates it's somewhat straight forward. For keys, it isn't obvious to some if they would be using PRIVATE KEY, RSA PRIVATE KEY, ENCRYPTED PRIVATE KEY, etc.

See #51597 for some additional context.

Proposed API

namespace System.Security.Cryptography
{
    public partial class AsymmetricAlgorithm
    {
        public string ExportPkcs8PrivateKeyPem();
        public bool TryExportPkcs8PrivateKeyPem(Span<char> buffer, out int charsWritten);

        public string ExportEncryptedPkcs8PrivateKeyPem(ReadOnlySpan<char> password, PbeParameters pbeParameters);
        public bool TryExportEncryptedPkcs8PrivateKeyPem(ReadOnlySpan<char> password, PbeParameters pbeParameters, Span<char> destination, out int charsWritten);

        public string ExportSubjectPublicKeyInfoPem();
        public bool TryExportSubjectPublicKeyInfoPem(Span<char> destination, out int charsWritten);
    }

    public partial class RSA
    {
        public string ExportRSAPrivateKeyPem();
        public string ExportRSAPublicKeyPem();

        public bool TryExportRSAPrivateKeyPem(Span<char> destination, out int charsWritten);
        public bool TryExportRSAPublicKeyPem(Span<char> destination, out int charsWritten);
    }

    public partial class ECDsa
    {
        public string ExportECPrivateKeyPem();
        public bool TryExportECPrivateKeyPem(Span<char> destination, out int charsWritten);
    }

    public partial class ECDiffieHellman
    {
        public string ExportECPrivateKeyPem();
        public bool TryExportECPrivateKeyPem(Span<char> destination, out int charsWritten);
    }

    // DSA does not have anything beyond what it gets from AsymmetricAlgorithm
}

namespace System.Security.Cryptography.X509Certificates
{
    public partial class X509Certificate2
    {
        public string ExportCertificatePem();
        public bool TryExportCertificatePem(Span<char> buffer, out int charsWritten);
    }

    public partial class X509Certificate2Collection
    {
        // Exports a PEM aggregate of all certificates
        public string ExportCertificatePems();
        public bool TryExportCertificatePems(Span<char> buffer, out int charsWritten);

        // Exports a single PKCS7 PEM of all certificates
        public string ExportPkcs7Pem();
        public bool TryExportPkcs7Pem(Span<char> buffer, out int charsWritten);
    }
}

Usage Examples

string certPem = someCert. ExportCertificatePem();
// do something with the PEM

Alternative Designs

We do nothing and better document PEMs, labels, and using PemEncoding.

Risks

Not aware of any.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions