Open vcsjones opened 1 year ago
Tagging subscribers to this area: @dotnet/area-system-security, @vcsjones See info in area-owners.md if you want to be subscribed.
Author: | vcsjones |
---|---|
Assignees: | - |
Labels: | `api-suggestion`, `area-System.Security` |
Milestone: | - |
Amusingly, I was just answering an SO question yesterday where someone had an AES-256/SHA-256 PFX that they couldn't load (because it was being loaded by Mono, which doesn't support the newer revision with PBES2).
The version with the enum is probably a good balance of allowing more modern algorithm choices without impeding a common operating too much... but I wonder if we should just go ahead and overload it with PbeParameters at the same time to allow the much richer control.
We should add TripleDes192Sha1 to the enum now, though, so that we can have "Default means we pick, but you have the option of specifying 'legacy' if we ever change the defaults".
It's a Window 10 1709+ API. This will throw PNSE on down level Windows if Pbes2Aes256Sha256 is supplied.
We could probably avoid the PNSE and just have both the OS-exporter and our custom-exporter available on Windows.
@bartonjs
We could probably avoid the PNSE and just have both the OS-exporter and our custom-exporter available on Windows.
I thought about that but.. I got a little concerned about all of the Win32-isms and Bag Attributes that get applied. It might be surprising to folks that using AES means "you don't get a keyAttributes on your PKCS12 bag anymore". But maybe that is acceptable for Windows 8 / Server 2012.
We should add TripleDes192Sha1 to the enum now, though, so that we can have "Default means we pick, but you have the option of specifying 'legacy' if we ever change the defaults".
That makes sense if we are okay with using a managed export on Windows. Win32 doesn't let us explicitly pick TripleDes192Sha1
. It lets us pick "Whatever the OS decides" and "Aes256Sha256". Is there a world in which Windows changes their own default?
but I wonder if we should just go ahead and overload it with PbeParameters at the same time to allow the much richer control.
My concern is largely the same as the first one, where if on Windows you use the managed one, you might not get all of the bag attributes that Windows likes to shove in there.
If we're okay losing bag attributes on Windows... then... I guess we can do PbeParameters
and 3DES on the enumeration.
Worst case: we could always let Windows export it, then we decompose and recompose it with the better algorithms...
we could always let Windows export it, then we decompose and recompose it with the better algorithms...
I am annoyed that did not occur to me. This sounds reasonable to me, and should make it (relatively) straight forward to make this work with any set of PbeParameters
. In that sense then I'm not sure there is much value in using the new Win32 API at all. We can just use the old one, crack it open, and re-encode it.
I'll adjust the proposal.
It also occurs to me that we probably want symmetry with X509Certificate2Collection
Looks good as proposed.
We discussed replacing the enum with prepopulated accelerators on PbeParameters, but the enum values don't specifically encode the iteration count (where we're following OS defaults).
namespace System.Security.Cryptography.X509Certificates;
public partial class X509Certificate {
public byte[] ExportPkcs12(Pkcs12ExportPbeParameters exportParameters, string? password);
public byte[] ExportPkcs12(PbeParameters exportParameters, string? password);
}
public partial class X509Certificate2Collection {
public byte[] ExportPkcs12(Pkcs12ExportPbeParameters exportParameters, string? password);
public byte[] ExportPkcs12(PbeParameters exportParameters, string? password);
}
public enum Pkcs12ExportPbeParameters {
// Initially will behave as `Pbes2TripleDesSha1`, but reserved to change behavior in the future.
Default = 0,
// TripleDes3KeyPkcs12, SHA1, 2000 PBKDF2 rounds. Matches Win32.
Pbes2TripleDesSha1 = 1,
// AES-256, SHA256, 2000 PBKDF2 rounds. Matches Win32.
Pbes2Aes256Sha256 = 2,
}
Background and motivation
Right now
Export(X509ContentType.Pkcs12, ...)
assumes 3DES, SHA1, and 2000 rounds of PBKDF. These are not great in 2023 and there is no control over it today. Developers could usePkcs12Builder
themselves, but, that's a fairly low-level mechanism that requires understanding how PKCS12 works.I propose we expose new APIs that allow stronger PKCS12 exports.
In the proposal, there are two overloads. An enum that provides simple options that match Windows behavior. The second is
PbeParameters
where people can have total control over the encryption, hash, and number ob PBES2 rounds.Win32 by default does not give us the flexibility that is needed to implement
PbeParameters
, as it does not let us choose the number of PBES2 rounds. In that case, the export will be performed using an existing Win32 API, decoded, and re-encoded with the managed implementation using the specified parameters.API Proposal
API Usage