-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Exporting Certificate with a password always chooses SHA1-3DES encryption #108330
Comments
Tagging subscribers to this area: @dotnet/area-system-security, @bartonjs, @vcsjones |
There is an API that is approved - but not implemented - to allow selecting PBE parameters during export over at #80314. In the mean time, you can use Something like this (I only lightly tested this) using System.Security.Cryptography;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;
static byte[] ExportPkcs12(X509Certificate2 certificate, string password)
{
Pkcs9LocalKeyId keyId = new([1]);
PbeParameters pbe = new(PbeEncryptionAlgorithm.Aes256Cbc, HashAlgorithmName.SHA256, 100_000);
using AsymmetricAlgorithm? key = (AsymmetricAlgorithm?)certificate.GetRSAPrivateKey() ?? certificate.GetECDsaPrivateKey();
if (key is null)
throw new CryptographicException("No private key");
Pkcs12Builder builder = new();
Pkcs12SafeContents certContainer = new();
Pkcs12SafeContents keyContainer = new();
Pkcs12SafeBag certBag = certContainer.AddCertificate(certificate);
Pkcs12SafeBag keyBag = keyContainer.AddShroudedKey(key, password, pbe);
certBag.Attributes.Add(keyId);
keyBag.Attributes.Add(keyId);
// Change to AddSafeContentsUnencrypted if you do not want the certificate encrypted in PKCS12
builder.AddSafeContentsEncrypted(certContainer, password, pbe);
//key safe contents do not need to be encrypted because the key is shrouded.
builder.AddSafeContentsUnencrypted(keyContainer);
builder.SealWithMac(password, pbe.HashAlgorithm, pbe.IterationCount);
return builder.Encode();
} |
Keep in mind that some platforms, such as macOS and older Windows are not capable of working with "modern" PBE encryption at the operating system level. For example, Windows Server 2012 R2 may not be able to import an AES encrypted PFX/PCKS12. |
Description
When exporting a
X509Certificate2
with a password, the method will always encrypt the key with the same encryption. SHA1-3DES.This encryption is slightly weak, and while it's probably good enough in this use case I cannot find a way to export it with any other encryption. There is a way to export only the key with variable encryption, but not the certificate.
This is also present when importing certificates (pfx) where the key is encrypted with AES, after exporting it again it's back to SHA1-3DES.
Reproduction Steps
The keybag will always have that encryption.
Expected behavior
The API does not allow input on encryption used. But, the expected behavior is that it would use some sort of "best effort" where better encryption is available should be used.
Actual behavior
Always selects SHA1-3DES encryption.
Regression?
No response
Known Workarounds
There is a way to encrypt the key alone with a different encryption and use other tools to merge the certificate (without private key) file with the private key file.
Configuration
This is present in .NET Framework and .NET 8 (Tested in both configurations)
Tested on Windows 10, 11, Server 2016.
Other information
No response
The text was updated successfully, but these errors were encountered: