Библиотека Argon2, которая хэширует пароли без секрета и со случайной солью, которая не выглядит разборчивой - PullRequest
1 голос
/ 16 октября 2019

Я смотрю на различные альтернативы хеш-паролям в приложении Python. Сначала я согласился на Flask-bcrypt (https://github.com/maxcountryman/flask-bcrypt),, но затем решил использовать Argon2. Наиболее популярные привязки Argon2 для Python - это argon2-cffi (https://github.com/hynek/argon2-cffi).

Согласно его 'документам (https://argon2 -cffi.readthedocs.io / en / stable / api.html ), все что мне нужно сделать, это использовать 3 метода:

  • hash для хеширования пароля
  • verify для сравнения пароля с хешем
  • check_needs_rehash, чтобы узнать, следует ли перефразировать пароль после изменения параметров хеширования

Двавещи меня озадачивают.

1) Соль случайная, с использованием os.urandom. Поэтому я задаюсь вопросом, может ли метод verify каким-либо образом извлечь соль из хеша? Или другими словами, так как у меня естьНельзя сказать, что такое соль, и не может ее сохранить, как метод verify может фактически сравнивать любой пароль с паролем, который был хеширован со случайной солью? Должен ли я каким-то образом анализировать соль из возвращаемого значения * 1027? * и хранить его отдельно от хешированного значения? Или хеш должен бытьхранится как есть в документации, нетронутый, и каким-то образом Argon2 способен проверить пароль против него? И если действительно Argon2 может извлекать соль из хеша, как безопаснее использовать соль в этом случае, поскольку враждебная сущность, которая получает хешированный пароль, должна также иметь возможность извлечь соль?

2)По умолчанию я не предоставляю какой-либо секрет методу hash, и вместо этого сам пароль кажется секретным. Это безопасно? Какие у меня минусы, не секрет секрета метода хеширования?

Ответы [ 2 ]

3 голосов
/ 16 октября 2019

1) Соль случайная, с использованием os.urandom. Поэтому мне интересно, может ли метод verify каким-либо образом извлечь соль из хеша?

Метод hash возвращает строку, которая кодирует соль, параметры иСам хэш пароля, как показано в документации:

>>> from argon2 import PasswordHasher
>>> ph = PasswordHasher()
>>> hash = ph.hash("s3kr3tp4ssw0rd")
>>> hash  
'$argon2id$v=19$m=102400,t=2,p=8$tSm+JOWigOgPZx/g44K5fQ$WDyus6py50bVFIPkjA28lQ'
>>> ph.verify(hash, "s3kr3tp4ssw0rd")
True

Формат суммируется в эталонной реализации Argon2 ;возможно, есть и другие ссылки. В этом случае:

  1. $argon2id$...

    Хешем является Argon2id, который является конкретным вариантом Argon2, который должен использовать каждый (объединяя сопротивление бокового канала Argon2i сболее сложный для взлома Argon2d).

  2. ...$v=19$...

    Версия хэша 0x13 (19 десятичных знаков), что означает Argon2 v1.3, версияпринятый Конкурс хэширования паролей .

  3. ...$m=102400,t=2,p=8$...

    Использование памяти составляет 100 МБ (102400 КБ), время составляет 2 итерациии параллелизм 8 способов.

  4. ...$tSm+JOWigOgPZx/g44K5fQ$...

    Соль tSm+JOWigOgPZx/g44K5fQ (base64) или b5 29 be 24 e5 a2 80 e8 0f 67 1f e0 e3 82 b9 7d (шестнадцатеричный).

  5. ...$WDyus6py50bVFIPkjA28lQ

    Сам хэш пароля равен WDyus6py50bVFIPkjA28lQ (base64) или 58 3c ae b3 aa 72 e7 46 d5 14 83 e4 8c 0d bc 95 (шестнадцатеричный).

Метод verify берет эту строку и пароль-кандидат, пересчитывает хэш пароля со всеми закодированными параметрами и сравнивает его с хэшем закодированного пароля.

И если действительно, Argon2 можетизвлечь соль из хеша, как безопаснее использовать соль в этом случае, поскольку враждебная сущность, которая получает хешированный пароль, должна также иметь возможность извлечь соль?

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

  • Если все использовали то же самое соль, а затем злоумышленник, пытающийся найти сначала из $ n $ паролей данных хэшей, потребуется потратить всего около $ 1 / n $ стоимости, которую злоумышленник пытаетсячтобы найти один конкретный пароль , учитывая его хэш, придется потратить. Кроме того, злоумышленник может ускорить взлом отдельных паролей, выполнив дорогостоящее предварительное вычисление (радужные таблицы).

  • Но если каждый использует различную сольтогда это преимущество пакета или преимущество предварительного вычисления исчезает.

Выбор соли равномерно случайным образом среди 32-байтовых строк - это просто простой способ гарантировать, что у каждого пользователя есть отдельная соль. В принципе, можно представить себе орган, раздающий всем в мире последовательные числа для использования в качестве соли Argon2, но эта система не очень хорошо масштабируется - я не просто имею в виду, что ваше приложение можетиспользуйте счетные полномочия, но каждое приложение в мире должно будет использовать такие же счетные полномочия, и я думаю, что граф слишком занят на Улице Сезам, чтобы выполнять эту работу.

2) По умолчанию я не предоставляю какой-либо секрет методу hash, и вместо этого сам пароль кажется секретным. Это безопасно? Какие минусы для меня, не предоставляя секрет для метода хеширования?

Обычно пароль является секретом: если кто-то знает пароль, то они должныиметь возможность войти в систему;если они не знают пароль, им должны показать дверь!

Тем не менее, Argon2 также поддерживает секретный ключ, который отделен от солии отдельно от пароля.

Если между вашей базой паролей и вашим приложением существует значимая граница безопасности, так что вполне вероятно, что злоумышленник может поставить под угрозу одно, но не другое, тогда приложение может выбрать единую случайную 32-байтовую строку в качестве секретного ключа и использовать ее с Argon2, чтобы хэш пароля был секретной функцией секретного пароля.

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

0 голосов
/ 16 октября 2019

Вывод хеша на самом деле является кодировкой хеша, параметров хеша и соли. Вам не нужно делать с этим ничего особенного, просто храните его как обычно.

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

...