PBKDF2 с использованием SHA 256 в .NET - PullRequest
0 голосов
/ 11 июня 2018

Мне нужно обновить код, который использует реализацию PBKDF2 в .Net, Rfc2898DeriveBytes для хеширования учетных данных пользователя.Насколько я понимаю, эта функция использует SHA-1 под капотом.Мне нужно обновить базовый алгоритм хеширования паролей системы для использования SHA-256 (это требование IT-SEC клиента).

Пройдя некоторое чтение, кажется, что лучше продолжать использовать функцию деривации ключей, однако PBKDF2 не позволяет вам диктовать алгоритм, который следует использовать, что, очевидно, является проблемой для меня.

Наша система использует .NET 4.5.1, и в настоящее время нет возможности обновить ее, и я уверен, что это не вариант ссылки на какие-либо новые .NET core .dll, которые, как я слышал, содержат новуюреализация PBKDF2, которая позволяет вам задавать свой алгоритм.

Я хочу избегать самодельных реализаций любой ценой, так как это первое правило Крипто-Клуба, верно?

Любое руководство о том, чтоЛучшая практика будет оценена.

Спасибо

Ответы [ 3 ]

0 голосов
/ 11 июня 2018

Я расскажу вам, что я буду делать: я бы взял источник самого нового (не совсем нового, потому что он использует Span<> ... Просто немного старше :-)) из Rfc2898DeriveBytes из corefx github

Вам понадобится полный код:

плюс два метода (GenerateRandom и WriteInt) из

Тогда у вас будетнекоторые вызовы на SR.*something*, которые вам придется заменить на некоторые сообщения, такие как "some error", плюс SR.Format, которые вы должны заменить на string.Format.

Тогда вы получите (почти)новейшая версия Rfc2898DeriveBytes, которая имеет конструктор, принимающий в качестве параметра HashAlgorithmName.SHA256.

Это должно быть конечным результатом: https://ideone.com/lb2Qya

У меня была плохая идея поставитьисходный код в пространстве имен My.System ... плохая плохая идея ... Мне пришлось поставить префикс global:: во всех пространствах имен: - (

0 голосов
/ 11 июня 2018

Вы можете P / Invoke набрать BCryptDeriveKeyPBKDF2 , при условии, что вы используете Win7 +.

private static void PBKDF2(
    string password,
    byte[] salt,
    int iterationCount,
    string hashName,
    byte[] output)
{
    int status = SafeNativeMethods.BCryptOpenAlgorithmProvider(
        out SafeNativeMethods.SafeBCryptAlgorithmHandle hPrf,
        hashName,
        null,
        SafeNativeMethods.BCRYPT_ALG_HANDLE_HMAC_FLAG);

    using (hPrf)
    {
        if (status != 0)
        {
            throw new CryptographicException(status);
        }

        byte[] passBytes = Encoding.UTF8.GetBytes(password);

        status = SafeNativeMethods.BCryptDeriveKeyPBKDF2(
            hPrf,
            passBytes,
            passBytes.Length,
            salt,
            salt.Length,
            iterationCount,
            output,
            output.Length,
            0);

        if (status != 0)
        {
            throw new CryptographicException(status);
        }
    }
}

[SuppressUnmanagedCodeSecurity]
private static class SafeNativeMethods
{
    private const string BCrypt = "bcrypt.dll";
    internal const int BCRYPT_ALG_HANDLE_HMAC_FLAG = 0x00000008;

    [DllImport(BCrypt, CharSet = CharSet.Unicode)]
    [DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
    internal static extern int BCryptDeriveKeyPBKDF2(
        SafeBCryptAlgorithmHandle hPrf,
        byte[] pbPassword,
        int cbPassword,
        byte[] pbSalt,
        int cbSalt,
        long cIterations,
        byte[] derivedKey,
        int cbDerivedKey,
        int dwFlags);

    [DllImport(BCrypt)]
    [DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
    private static extern int BCryptCloseAlgorithmProvider(IntPtr hAlgorithm, int flags);

    [DllImport(BCrypt, CharSet = CharSet.Unicode)]
    [DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
    internal static extern int BCryptOpenAlgorithmProvider(
        out SafeBCryptAlgorithmHandle phAlgorithm,
        string pszAlgId,
        string pszImplementation,
        int dwFlags);

    internal sealed class SafeBCryptAlgorithmHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        public SafeBCryptAlgorithmHandle() : base(true)
        {
        }

        protected override bool ReleaseHandle()
        {
            return BCryptCloseAlgorithmProvider(handle, 0) == 0;
        }
    }
}
0 голосов
/ 11 июня 2018

Вы можете указать алгоритм сейчас, Страница MSDN

Примечание: Доступно с 4.7.2

Имена доступны в System.Security.Cryptography.HashAlgorithmName

...