Как проверить пароль по хешу?

Я изучаю Flask с помощью замечательного учебника Мигель Гринберг. В этой главе он предлагает хранить хэш пароля пользователя, а не сам пароль по соображениям безопасности. Используемые функции: generate_password_hash, check_password_hash. Но даже если вы вызовете generate_password_hash с той же строкой, вы можете получить разные хеш-значения:

Как проверить пароль по хешу?

>>> from werkzeug.security import generate_password_hash
>>> generate_password_hash('foo')
'pbkdf2:sha256:50000$E4Mg0BEy$c8db80b3ddefad78a93eaa47b22da5ce04adb969913b00545302cbf23501fdbb'
>>> generate_password_hash('foo')
'pbkdf2:sha256:50000$UCXVV09c$fe38b6099a0059957e283f2e4706fdbf01ef6e762b1070116df17867aa04e053'

Тогда как же работает check_password_hash, если одна и та же строка может иметь сколько угодно хеш-значений?

Это описано на странице Flask Соленые пароли и более подробно на Википедия. Ключевое слово: соль.

Amadan 30.10.2018 07:48
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
1
4 648
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

Это сделано для того, чтобы хакеры не могли просто угадать хэш общих паролей. Например, хэш «pass1234» каждый раз будет одинаковым. Однако хеш «pass1234 + salt» каждый раз будет отличаться. Ваша база данных должна хранить хэш, а также соль (что важно, а не пароль в виде обычного текста). Это минимизирует ущерб, причиненный утечкой информации об учетных записях пользователей.

В случае Flask и werkzeug возвращаемое значение generate_password_hash() имеет вид: method$salt$hash (вы можете увидеть два символа $ на предоставленном вами снимке экрана). Поэтому в следующий раз, когда вы проверите пароль в открытом виде по хешу, вы получите его со значением соли из generate_password_hash() и посмотрите, соответствует ли оно хеш-значению.

В Python Flask поле пароля таблицы user хранится в $6$rounds=656000$JW9ctR1i8kLbiFAZ$HymY4FLhinJbiyShgd1BvZI.iO‌​b6IwaXn0/rdNvmZfim2z‌​soP1FcPlUG.KX5Idl0wa‌​jXChSztnr5z1yRmwb.R/, как я могу проверить, соответствует ли это значение простому тексту пароля

mahes 21.03.2019 06:53

Then how does the check_password_hash work if the same string can have as many > hash values as it like?

Упрощенное решение может быть таким:

1) без соли

 user_id|  raw_password  |   hash_value  
  user1 |  'foo'         |  same_hashed_value      
  user2 |  'foo'         |  same_hashed_value
   

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

2) с солью

сгенерировать хеш-процесс:

  user_id | raw_password  |   password_with_salt  |  hash_value   
   user1  |      'foo'    |  'foo#salt123'        |  different_hash_1   
   user2  |      'foo'    |  'foo#saltABC'        |  different_hash_2   

В этом случае hash_value и связанное с ним salt_value могут храниться в базе данных. В противном случае, concat (hash_vaule, salt_value) как одна строка для хранения, что эквивалентно.

проверить хеш-процесс:

1) Получить из базы данных значение salt_value и hash_value. 2) Добавьте salt_value к заданному паролю и хешируйте его, используя ту же хеш-функцию. 3) Сравните хэш данного пароля с хешем из базы данных. Если они совпадают, пароль правильный. В противном случае пароль неверный.

Другие вопросы по теме