-
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
Question: how to generate a .pem file with private key from an X509Certificate2? #51597
Comments
Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq, @GrabYourPitchforks Issue DetailsDescriptionMay I know if there is any way to generate a .pem file with private key from an X509Certificate2?
2.Wrote a console to:
I could see non empty char arrays for above certificatePem, pubKeyPem and privKeyPem. But I'm not sure how to combine them into a .pem file. I'm wondering if you know how to generate a .pem file with private key (with or without password) from an X509Certificate2 cert? Thanks! Attached is the cert file from step1. ConfigurationRegression?Other information
|
You should be able to do something like this: string certPem = new string(PemEncoding.Write("CERTIFICATE", cert.RawData));
string keyPem;
if (cert.GetRSAPrivateKey() is RSA rsaKey)
{
keyPem = new string(PemEncoding.Write("PRIVATE KEY", rsaKey.ExportPkcs8PrivateKey()));
}
else if (cert.GetECDsaPrivateKey() is ECDsa ecdsaKey)
{
keyPem = new string(PemEncoding.Write("PRIVATE KEY", ecdsaKey.ExportPkcs8PrivateKey()));
}
else if (cert.GetDSAPrivateKey() is DSA dsaKey)
{
keyPem = new string(PemEncoding.Write("PRIVATE KEY", dsaKey.ExportPkcs8PrivateKey()));
}
else
{
throw new CryptographicException("Unknown certificate algorithm");
}
Console.WriteLine(certPem);
Console.WriteLine(keyPem);
var certAgain = X509Certificate2.CreateFromPem(certPem, keyPem); That will export the private key in to a PEM-encoded PKCS8 private key. |
If you want to use PbeParameters pbe = new PbeParameters(PbeEncryptionAlgorithm.Aes128Cbc, HashAlgorithmName.SHA256, 600_000);
var certPem = new string(PemEncoding.Write("CERTIFICATE", cert.RawData));
string keyPem;
if (cert.GetECDsaPrivateKey() is ECDsa ecdsaKey)
{
keyPem = new string(PemEncoding.Write("ENCRYPTED PRIVATE KEY", ecdsaKey.ExportEncryptedPkcs8PrivateKey("test", pbe)));
}
else if (cert.GetRSAPrivateKey() is RSA rsaKey)
{
keyPem = new string(PemEncoding.Write("ENCRYPTED PRIVATE KEY", rsaKey.ExportEncryptedPkcs8PrivateKey("test", pbe)));
}
else if (cert.GetDSAPrivateKey() is DSA dsaKey)
{
keyPem = new string(PemEncoding.Write("ENCRYPTED PRIVATE KEY", dsaKey.ExportEncryptedPkcs8PrivateKey("test", pbe)));
}
else
{
throw new CryptographicException("Unknown certificate algorithm");
}
Console.WriteLine(certPem);
Console.WriteLine(keyPem);
var certAgain = X509Certificate2.CreateFromEncryptedPem(certPem, keyPem, "test"); |
And finally, if you want to combine them, one more example: string aggregatePem = certPem + "\n" + keyPem;
var certAgain = X509Certificate2.CreateFromPem(aggregatePem, aggregatePem); Or if you write the combined contents to a file: string aggregatePem = certPem + "\n" + keyPem;
File.WriteAllText("combined.pem", aggregatePem);
var certAgain = X509Certificate2.CreateFromPemFile("combined.pem"); And for encrypted private key PEMs it would be the same but using the |
Thanks a lot for your help! @vcsjones |
@vcsjones This feels like recipe we should document somewhere |
Yeah. Part of me is wondering though if there is a quality-of-life API that's missing. Something like: public class X509Certificate2 {
public string ExportCertificatePem();
public bool TryExportCertificatePem(Span<char> buffer, out int bytesWritten);
}
public class AsymmetricAlgorithm {
public string ExportPkcs8PrivateKeyPem();
public bool TryExportPkcs8PrivateKeyPem(Span<char> buffer, out int bytesWritten);
public string TryExportEncryptedPkcs8PrivateKeyPem();
public bool TryExportEncryptedPkcs8PrivateKeyPem(Span<char> buffer, out int bytesWritten);
} Maybe @bartonjs has more thoughts on this. |
We could add it, but there are some corner cases.
|
My thought was that is easy enough. Concatenating two strings doesn't seem like an especially tall order.
And I thought passwordless was all the rage...
Personally I have never once used those formats in conjunction with a PEM. Or really ever.
Guess that can't hurt. I will open a new issue with a better formatted proposal (with password parameters!) so I don't hijack this issue any longer. |
The original question has been answered, and the "maybe there's room for improvement" is an API proposal, so I don't think anything's left from this issue. |
Description
May I know if there is any way to generate a .pem file with private key from an X509Certificate2?
I tried the following:
1.Create a self-issued X509Certificate2 certificate(cert) with private key (the key generation algorithm is RSA ), saved as attached file.
2.Wrote a console to:
1).Read the bytes, create an X509Certificate2 cert, Set a password to protect the cert.
2).Try to get the certificate, public key, private key to create a .pem file.
I could see non empty char arrays for above certificatePem, pubKeyPem and privKeyPem. But I'm not sure how to combine them into a .pem file.
I tried to convert them into string and concatenate them, but the .pem file generated in this way failed to be used in CreateFromEncryptedPemFile as CryptographicException as following:
cert = X509Certificate2.CreateFromEncryptedPemFile(options.CertificatePath, options.CertificatePassword)
The exception details is:
I'm wondering if you know how to generate a .pem file with private key (with or without password) from an X509Certificate2 cert? Thanks!
Attached is the cert file from step1.
cert.zip
Configuration
Regression?
Other information
The text was updated successfully, but these errors were encountered: