-
Notifications
You must be signed in to change notification settings - Fork 4.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
APIs for exporting certificates and keys to PEM #51630
Comments
Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq, @GrabYourPitchforks Issue DetailsBackground and MotivationIn .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 APInamespace 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
{
// Not thrilled with these names
public string ExportCertificatePem();
public bool TryExportCertificatePem(Span<char> buffer, out int charsWritten);
}
} Usage Examplesstring certPem = someCert. ExportCertificatePem();
// do something with the PEM Alternative DesignsWe do nothing and better document PEMs, labels, and using RisksNot aware of any.
|
For X509Certificate2Collection: |
Hmm. If we have export working for it, I would expect some import symmetry. |
Seems reasonable to me to do so. The Import method understands them. Or we could do ImportPkcs7Pem so we don't have the oh-so-un-fun "it works on 6, and silently skips it on 5" problem (since unknown labels are just skipped in the current method).
That makes sense, and suggests to me that you were expecting the export here to be a multi-PEM. Is that the case? If so, maybe just pluralize the method to "ExportCertificatePems"? |
Yeah. I don't see PKCS7 PEMs much. A multi-PEM gives symmetry with the
Hm. I would not have expressed concern over that. My general expectations for the
Although I don't think I'd expect a lot of folks to have CERTIFICATE and PKCS7 PEMs in the same bundle very often.
That seems reasonable. I added PKCS7 exports to the proposal since we may or may want them, at least as a point to consider. As far as the import, my immediate preference would be to improve the API we already have, but if that proves to be too contentious because of the silent skipping behavior, then I could be convinced (for all that it matters) that dedicated import methods make sense. |
Looks like this slipped through the cracks, sorry. If we had added the Import methods this release I'd perhaps try to rush this as scenario completion... but we added them last release, so it's scenario expansion. So I've marked it as 7.0. |
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);
}
}
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
{
public string ExportCertificatePems();
public bool TryExportCertificatePems(Span<char> buffer, out int charsWritten);
public string ExportPkcs7Pem();
public bool TryExportPkcs7Pem(Span<char> buffer, out int charsWritten);
}
} |
@bartonjs I noticed in the proposal that the in the Try- X.509 certificate exporting the receiving span is called |
Nope, |
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:
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
Usage Examples
Alternative Designs
We do nothing and better document PEMs, labels, and using
PemEncoding
.Risks
Not aware of any.
The text was updated successfully, but these errors were encountered: