Хэш-пароли в ASP.NET Core

В этой статье показано, как вызвать метод KeyDerivation.Pbkdf2, позволяющий хэшировать пароль с помощью алгоритма PBKDF2, как описано в разделе 5.2 RFC 2898.

KeyDerivation.Pbkdf2 API — это низкоуровневый криптографический примитив. Предназначено для интеграции приложений в существующую протокол или криптографическую систему.

Предупреждение

KeyDerivation.Pbkdf2 не следует использовать в новых приложениях, поддерживающих вход на основе паролей и которые должны хранить хэшированные пароли в хранилище данных. Новые приложения должны использовать класс PasswordHasher . Дополнительные сведения см. в разделе Exploring ASP.NET Core Identity PasswordHasher.

База кода защиты данных включает пакет NuGet Microsoft. AspNetCore.Cryptography.KeyDerivation который содержит функции производного ключа шифрования. Этот пакет является автономным компонентом и не имеет зависимостей от остальной части системы защиты данных. Пакет можно использовать независимо. Источник существует вместе с базой кода защиты данных в качестве удобства.

Создание ключа с помощью KeyDerivation.Pbkdf2

В следующем коде показано, как использовать KeyDerivation.Pbkdf2 метод для создания общего секретного ключа.

Предупреждение

Не вызывайте KeyDerivation.Pbkdf2 метод хэширования пароля для хранения в хранилище данных.

using Microsoft.AspNetCore.Cryptography.KeyDerivation;
using System.Security.Cryptography;

Console.Write("Enter a password: ");
string? password = Console.ReadLine();

// Generate a 128-bit salt using a sequence of
// cryptographically strong random bytes.
byte[] salt = RandomNumberGenerator.GetBytes(128 / 8); // divide by 8 to convert bits to bytes
Console.WriteLine($"Salt: {Convert.ToBase64String(salt)}");

// derive a 256-bit subkey (use HMACSHA256 with 100,000 iterations)
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
    password: password!,
    salt: salt,
    prf: KeyDerivationPrf.HMACSHA256,
    iterationCount: 100000,
    numBytesRequested: 256 / 8));

Console.WriteLine($"Hashed: {hashed}");

/*
 * SAMPLE OUTPUT
 *
 * Enter a password: Xtw9NMgx
 * Salt: CGYzqeN4plZekNC88Umm1Q==
 * Hashed: Gt9Yc4AiIvmsC1QQbe2RZsCIqvoYlst2xbz0Fs8aHnw=
 */
using System;
using System.Security.Cryptography;
using Microsoft.AspNetCore.Cryptography.KeyDerivation;

public class Program
{
    public static void Main(string[] args)
    {
        Console.Write("Enter a password: ");
        string password = Console.ReadLine();

        // generate a 128-bit salt using a cryptographically strong random sequence of nonzero values
        byte[] salt = new byte[128 / 8];
        using (var rngCsp = new RNGCryptoServiceProvider())
        {
            rngCsp.GetNonZeroBytes(salt);
        }
        Console.WriteLine($"Salt: {Convert.ToBase64String(salt)}");

        // derive a 256-bit subkey (use HMACSHA256 with 100,000 iterations)
        string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
            password: password,
            salt: salt,
            prf: KeyDerivationPrf.HMACSHA256,
            iterationCount: 100000,
            numBytesRequested: 256 / 8));
        Console.WriteLine($"Hashed: {hashed}");
    }
}

/*
 * SAMPLE OUTPUT
 *
 * Enter a password: Xtw9NMgx
 * Salt: CGYzqeN4plZekNC88Umm1Q==
 * Hashed: Gt9Yc4AiIvmsC1QQbe2RZsCIqvoYlst2xbz0Fs8aHnw=
 */
 

Реальный вариант использования типа ASP.NET Core IdentityPasswordHasher см. в коде источника GitHub.

Примечание.

По ссылкам в документации на справочные материалы по .NET обычно загружается ветвь репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).