-
Notifications
You must be signed in to change notification settings - Fork 5k
ReadOnlySpan<byte> overloads for Rfc2898DeriveBytes constructors. #47466
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
Comments
Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq Issue DetailsBackground and MotivationRfc2898DeriveBytes constructors currently only accept a string or a byte array for the password and a byte array for the salt. In some cases a programmer might want to have them stored in a Span, passing them to the API requires a ToArray call which bloats the code and is an useless performance cost due to the constructors copying the data again. Proposed APInamespace System.Security.Cryptography
{
public class Rfc2898DeriveBytes : DeriveBytes {
+ public Rfc2898DeriveBytes(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, int iterations)
+ public Rfc2898DeriveBytes(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, int iterations, HashAlgorithmName hashAlgorithm)
+ public Rfc2898DeriveBytes(string password, ReadOnlySpan<byte> salt)
+ public Rfc2898DeriveBytes(string password, ReadOnlySpan<byte> salt, int iterations)
+ public Rfc2898DeriveBytes(string password, ReadOnlySpan<byte> salt, int iterations, HashAlgorithmName hashAlgorithm)
} Usage ExamplesReadOnlySpan<byte> salt = SomeMethodThatReturnsMemory().Span;
var rfc = new Rfc2898DeriveBytes("some password", salt); Alternative DesignsNone that I know of. RisksNone that I know of.
|
Hmm. A couple of thoughts.
That said, I think if allocations and performance are important to PBKDF2, a one-shot "no streaming" API would be better time spent focused on, instead of the stateful one that this class exposes. |
The only thing I'd maybe change is
I thought we had a proposal for that already. Looks like it was just a discussion point of #24897 (one of the benefits of the one-shot method is we can just call system implementations). |
TBH I agree with Kevin's comment above. I'd like to steer people away from creating an instance of this type + calling instance methods, in favor of calling the static one-shot. The instance members of this type have some weird internal logic which doesn't properly follow the RFC if called multiple times. The static one-shot properly follows the RFC. If we're going to steer people toward the one-shots, that's where our investments should be. |
I know PasswordDeriveBytes (PBKDF1) has some non-RFC behavior, but IIRC Rfc2898DeriveBytes (PBKDF2)'s only weirdness is that it's streaming. |
Static methods that'd take spans would also be fine, should I close this then? |
Yeah, we can continue the discussion on #24897, maybe you'd like to actually write a proposed API shape so we can mark it as ready for review. Without thinking very much: partial class Rfc2898DeriveBytes
{
public static byte[] DeriveKey(ROS<byte> passwordBytes, ROS<byte> salt, HashAlgorithmName hashAlgorithm, int iterationCount, int size);
public static byte[] DeriveKey(ROS<char> password, ROS<byte> salt, HashAlgorithmName hashAlgorithm, int iterationCount, int size);
public static byte[] DeriveKey(string password, ROS<byte> salt, HashAlgorithmName hashAlgorithm, int iterationCount, int size);
public static void DeriveKey(ROS<byte> passwordBytes, ROS<byte> salt, HashAlgorithmName hashAlgorithm, int iterationCount, Span<byte> destination);
public static void DeriveKey(ROS<char> password, ROS<byte> salt, HashAlgorithmName hashAlgorithm, int iterationCount, Span<byte> destination);
public static void DeriveKey(string password, ROS<byte> salt, HashAlgorithmName hashAlgorithm, int iterationCount, Span<byte> destination);
} But we can pick that apart over there. |
@vcsjones already did. ::whistles innocently::. OK, sounds like we don't have anything left for this one, so I'm going to go ahead and hit close. |
Background and Motivation
Rfc2898DeriveBytes constructors currently only accept a string or a byte array for the password and a byte array for the salt. In some cases a programmer might want to have them stored in a Span, passing them to the API requires a ToArray call which bloats the code and is an useless performance cost due to the constructors copying the data again.
Proposed API
Usage Examples
Alternative Designs
None that I know of.
Risks
None that I know of.
The text was updated successfully, but these errors were encountered: