Хеш на Unicode Пароль - PullRequest
       30

Хеш на Unicode Пароль

6 голосов
/ 16 ноября 2010

Я пишу соль / хэш-процедуру пароля для моего приложения .NET, в основном следуя руководству этой статьи: http://www.aspheute.com/english/20040105.asp

В основном код для вычисления соленого хэша таков:

public string ComputeSaltedHash(string password, byte[] salt) {

    // Get password ASCII text as bytes:
    byte[] passwordBytes = System.Text.Encoding.ASCII.GetBytes(password);

    // Append the two arrays
    byte[] toHash = new byte[passwordBytes.Length + salt.Length];
    Array.Copy(passwordBytes, 0, toHash, 0, passwordBytes.Length);
    Array.Copy(salt, 0, toHash, passwordBytes.Length, salt.Length);

    byte[] computedHash = SHA1.Create().ComputeHash(toHash);

    // Return as an ASCII string
    return System.Text.Encoding.ASCII.GetString(computedHash);
}

Однако я хочу разрешить пользователям использовать символы Unicode в своем пароле, если они захотят. (Это кажется хорошей идеей; кто-нибудь может придумать причину, по которой это не так?)

Однако я не знаю тонны о том, как работает Unicode, и я беспокоюсь, если я просто изменю обе ссылки с System.Text.Encoding.ASCII на System.Text.Encoding.Unicode, алгоритм хеширования может создать некоторые байтовые комбинации, которые не образуются допустимые символы Unicode и вызов GetString будет в шоке.

Это действительная проблема или все будет в порядке?

Ответы [ 3 ]

12 голосов
/ 16 ноября 2010

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

Я бы предложил:

  • Используйте Encoding.UTF8 для получения байтов из пароля.Это позволит паролю содержать любой символ Юникода.Encoding.Unicode здесь тоже подойдет.
  • Используйте Convert.ToBase64String для преобразования вычисленного хеша обратно в текст.Base64 специально разработан для представления непрозрачных двоичных данных в тексте в наборе символов ASCII.
2 голосов
/ 16 ноября 2010

Достаточно изменить первую ссылку на Unicode или UTF-8. Однако вы можете захотеть нормализовать ввод, чтобы учесть различные способы ввода акцентов и т. П.

0 голосов
/ 16 ноября 2010

Мне больше нравится решение Jon, но другой вариант - просто сохранить необработанный шестнадцатеричный код в виде строки. Замените свою последнюю строку на:

return BitConverter.ToString(computedHash)

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

Метод усиления паролей состоит в том, чтобы хэшировать его несколько раз, что увеличивает требования к процессору для хэширования. Возьмите выходные данные хэша SHA1 и передайте их в качестве входных данных для второго раунда. Сделайте это по крайней мере 1000 раз. Это замедляет вычисление хэша как для вас, так и для атакующего. Для ваших пользователей это задерживает доступ к тривиальному количеству времени; процедура вернется через 0,01 секунды вместо 0,0001 секунды. Однако для атаки грубой силой вы увеличили время выполнения в 1000 раз.

Вы можете свернуть свой собственный, но .net Framework предоставляет класс для этого: System.Security.Cryptography.Rfc2898DeriveBytes

RFC2898 использует алгоритм SHA1 и принимает простой текст, соль и количество итераций. Может выводить ключ переменной длины.

http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...