Skip to content

Improve performance of Rfc2898DeriveBytes #24897

Closed
@GrabYourPitchforks

Description

@GrabYourPitchforks

See aspnet/DataProtection#272 for full context.

ASP.NET has its own implementation of RFC2898 because it needs top-of-the-line performance for password hashing in order to have acceptable latency for login scenarios. If we bring these performance improvements to the framework's implementation of these APIs, ASP.NET can remove its own implementation and rely on the standard classes.

API Proposal

PBKDF2 technically starts with a password (that's what the "P" is), which is generally thought of as a string, but the algorithm operates on the bytes of a password, causing the always fun encoding selection problem.

Therefore there are two primary entrypoints, and then spanification thereof:

  • static byte[] PBKDF2(byte[] password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm, int outputLength)
  • static byte[] PBKDF2(string password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm, int outputLength) (calls the byte-based version after Encoding.UTF8)
namespace System.Security.Cryptography
{
    public partial class Rfc2898DeriveBytes
    {
        public static byte[] Pbkdf2DeriveBytes(
            byte[] password,
            byte[] salt,
            int iterations,
            HashAlgorithmName hashAlgorithm,
            int outputLength);

        public static byte[] Pbkdf2DeriveBytes(
            ReadOnlySpan<byte> password,
            ReadOnlySpan<byte> salt,
            int iterations,
            HashAlgorithmName hashAlgorithm,
            int outputLength);

        // uses destination.Length as outputLength.
        public static void Pbkdf2DeriveBytes(
            ReadOnlySpan<byte> password,
            ReadOnlySpan<byte> salt,
            Span<byte> destination,
            int iterations,
            HashAlgorithmName hashAlgorithm);

        public static byte[] Pbkdf2DeriveBytes(
            string password,
            byte[] salt,
            int iterations,
            HashAlgorithmName hashAlgorithm,
            int outputLength);

        public static byte[] Pbkdf2DeriveBytes(
            ReadOnlySpan<char> password,
            ReadOnlySpan<byte> salt,
            int iterations,
            HashAlgorithmName hashAlgorithm,
            int outputLength);

        public static void Pbkdf2DeriveBytes(
            ReadOnlySpan<char> password,
            ReadOnlySpan<byte> salt,
            Span<byte> destination,
            int iterations,
            HashAlgorithmName hashAlgorithm);
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions