Подтвердить что ты не робот

Заменить замену FormsAuthentication.HashPasswordForStoringInConfigFile?

После обновления до .Net 4.5 я получаю предупреждение о том, что "System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile устарел", и рекомендуется использовать API-интерфейсы членства.

Это все очень хорошо и хорошо для новых проектов, но на данном этапе (с пользовательскими данными и хешированными паролями) я не могу нормально переключиться на пользовательский поставщик членства с потенциально разными способами хэширования.

Каков рекомендуемый путь для таких проблем? Продолжение использования "устаревших" вызовов, очевидно, не является предлагаемым путем, поэтому его заменили чем-то другим, кроме "просто использовать API-интерфейсы членства"?

4b9b3361

Ответ 1

Это решение для варианта SHA1.

     public static string GetSwcSHA1(string value)
     {
        SHA1 algorithm = SHA1.Create();
        byte[] data = algorithm.ComputeHash(Encoding.UTF8.GetBytes(value));
        string sh1 = "";
        for (int i = 0; i < data.Length; i++)
        {
            sh1 += data[i].ToString("x2").ToUpperInvariant();
        }
        return sh1;
     }

Для MD5 вам нужно только изменить алгоритм на:

MD5 algorithm = MD5.Create();

Надеюсь, вы не против, просто добавив вариант VB.NET вашего кода выше:

    Public Shared Function CreateHash(saltAndPassword) As String
        Dim Algorithm As SHA1 = SHA1.Create()
        Dim Data As Byte() = Algorithm.ComputeHash(Encoding.UTF8.GetBytes(saltAndPassword))
        Dim Hashed As String = ""

        For i As Integer = 0 To Data.Length - 1
            Hashed &= Data(i).ToString("x2").ToUpperInvariant()
        Next

        Return Hashed
    End Function

Ответ 2

Каков рекомендуемый путь для таких проблем? Продолжение использования "устаревших" вызовов, очевидно, не является предлагаемым путем, поэтому его заменили чем-то другим, кроме "просто использовать API-интерфейсы членства"?

Лучший способ (который вы исключили) исключительно в рамках .NET Framework - все это изменить, чтобы пароли хэшировали PBKDF2, Bcrypt или Scrypt. PBKDF2 предоставляется в .NET с помощью класса Rfc2898DeriveBytes.

Вторым лучшим способом является использование двух "версий" паролей:

  • Версия 0 была бы старой версией HashPasswordForStoringInConfigFile, но вы можете обновлять ее в массовом порядке, в автономном режиме до версии 1 и удалять эти старые хэши целиком, прежде чем кто-нибудь их украдет, и вы попадете в торговые новости, имея жалкое 90-х старое хеширование паролей.
  • Версия 1, которая является PBKDF2 существующего значения HashPasswordForStoringInConfigFile! То есть вы берете свои текущие неприятные старые хеши, и PBKDF2 их с новой случайной солью и большим количеством итераций, и сохраняйте результат. Затем, когда пользователь хочет войти в систему, вы передаете свой пароль на код @RichardBažant, поэтому у вас есть то, что HashPasswordForStoringInConfigFile вернет, а затем вы примените PBKDF2 к этому результату!
    • то есть. это фактически Rfc2898DeriveBytes (HashPasswordForStoringInConfigFile (пароль)), PerUserSalt, YourIterations)
  • Версия 2, для которой пользователи, у которых есть хеш-версия 1, обновлены. Все столбцы, кроме "версии", одинаковы, но после вычисления и проверки версии 1 вы вычисляете Rfc2898DeriveBytes (пароль), PerUserSalt, YourIterations) и заменяете хэш-версию версии 1 хешей версии 2 (и меняете версию на 2, конечно).

Третий лучший способ - второй лучший способ, но только с версией 1. Будьте осторожны, таким образом DCC2 безумие - вы продолжаете обертывание ваш старый вывод внутри новых алгоритмов

В обоих случаях вы будете хранить результаты PBKDF2-HMAC-SHA-1 в базе данных, поэтому вам понадобится:

  • Пароль hash (BINARY (20)) - то есть выход PBKDF2.
  • Ваша соль (BINARY (16), созданная для каждого пользователя RNGCryptoServiceProvider Class)
  • Необязательно: количество итераций PBKDF2 (INT, начинающиеся с десятков тысяч и выше до того, как ваш сервер будет загружен с максимальной нагрузкой на CPU, увеличится по мере обновления вашего оборудования)
    • Это позволяет вам прозрачно повышать уровень безопасности каждый раз, когда пользователь вводит свой (правильный) пароль. Сначала проверяя его правильность, а затем повторно запустив его с более высоким числом итераций.
  • Необязательно: "версия" (TINYINT), так что позже перейти к другому алгоритму проще, так как вы можете иметь сразу несколько версий.

P.S. для нового алгоритма версии 1 или версии 2 Jither создал библиотеку .NET, способную к PBKDF2-HMAC-SHA256, PBKDF2-HMAC-SHA512 и т.д.; мой репозиторий Github содержит его вариант с разумным набором тестовых векторов.

Ответ 3

Ответ Ричарда работал у меня отлично. Это код, скомпилированный из .NET Framework 4.5. Если кто-то лучше, используйте его. Я думаю, это может быть немного быстрее.

        public static string BinaryToHex(byte[] data)
        {
            if (data == null)
            {
                return null;
            }
            char[] hex = new char[checked((int)data.Length * 2)];
            for (int i = 0; i < (int)data.Length; i++)
            {
                byte num = data[i];
                hex[2 * i] = NibbleToHex((byte)(num >> 4));
                hex[2 * i + 1] = NibbleToHex((byte)(num & 15));
            }
            return new string(hex);
        }

        private static char NibbleToHex(byte nibble)
        {
            int aChar = (nibble < 10 ? nibble + 48 : nibble - 10 + 65);
            return (char)aChar;
        }

Ответ 4

Почему нельзя использовать простейшую версию .Net

public static string HashString(string inputString, string hashName)
{
  var algorithm = HashAlgorithm.Create(hashName);
  if (algorithm == null)
     throw new ArgumentException("Unrecognized hash name", hashName);

  byte[] hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(inputString));
  return Convert.ToBase64String(hash);
}