Чи безпечніше хеш-пароль кілька разів?


43

Я декілька разів читав, що під час зберігання паролів є хорошою практикою "подвійного хешування" рядків (наприклад, з md5, потім sha1, як із солями, очевидно).

Я здогадуюсь, що перше питання: "чи це насправді правильно?" Якщо ні, то, будь ласка, відхиліть решту цього питання :)

Причина, яку я запитую, полягає в тому, що, маючи на увазі, я б сказав, що це має сенс. Однак, коли я замислююся над цим, щоразу, коли хеш переробляють (можливо, із чимось доданим до нього), все, що я бачу, - це зменшення верхньої межі остаточної "унікальності" ... що пов'язане з цим початковий вхід.

Дозвольте сказати іншим чином: у нас є x кількість рядків, які при хешеванні зводяться до y можливих рядків. Тобто, у першому наборі є зіткнення. Тепер, переходячи від другого набору до третього, чи не можливо, щоб відбулося те саме (тобто зіткнення в наборі всіх можливих рядків 'y', що призводять до того ж хешу в третьому наборі)?

У моїй голові все, що я бачу, - це «воронка» для кожного виклику хеш-функції, «перенаправлення» нескінченного набору можливостей у кінцевий набір тощо, але, очевидно, кожен виклик працює над кінцевим набором перед ним, даючи нам встановити не більше входу.

Можливо, приклад пояснить мої мітинги? Візьміть 'hash_function_a', який дасть 'a' і 'b' хеш '1', і дасть 'c' і 'd' хеш '2'. Використовуючи цю функцію для зберігання паролів, навіть якщо пароль "a", я можу використовувати пароль "b".

Візьміть "hash_function_b", який дасть "1" і "2" хеш "3". Якщо я мав би використовувати його як "вторинний хеш" після "hash_function_a", то навіть якщо пароль "a", я міг би використовувати "b", "c" або "d".

На додаток до всього, я розумію, що солі слід використовувати, але вони насправді не змінюють факту, що кожного разу, коли ми відображаємо входи "x" на виходи "менше x". Я не думаю

Може хтось, будь ласка, пояснить мені, що це таке, що я пропускаю тут?

Дякую!

EDIT: для чого це варто, я цього не роблю сам, використовую bcrypt. І мене не дуже хвилює питання про те, чи корисно це для "використання циклів" для "хакера". Мені справді цікаво, чи знижує процес зменшення «безпеки» з точки зору хеш-зіткнення.


2
@ S.Lott: Я насправді не бачу, як це відповідає на власне питання, хоча ... все, що там сказано, - або "не роби сам, використовуй цю річ", або "добре зайняти час!". .. жоден з яких не відповідає "чи це насправді більш безпечно". Знову ж таки, якщо я чогось не пропускаю.
Нарцис

@MetalMikester: Так, це була вчорашня стаття: thedailywtf.com/Articles/Bulletproof-Encryption.aspx
FrustratedWithFormsDesigner

Це не є темою для ІТ-безпеки, але це схоже на хороший збіг для криптографії. Насправді це виглядає надзвичайно схоже на це питання там .

Я знаю про компанію, яка хотіла використовувати несолоне MD5(password). Ми сказали, що це не безпечно, тому вони запропонували використати MD5(MD5(password))натомість ...
конфігуратор

Прийнята відповідь не є правильною відповіддю!
Маркус

Відповіді:


27

Це більше підходить для security.stackexchange, але ...

Проблема з

hash1(hash2(hash3(...hashn(pass+salt)+salt)+salt)...)+salt)

полягає в тому, що це лише настільки сильно, як і найслабша хеш-функція в ланцюжку. Наприклад, якщо хеш (найпотужніший хеш) дає зіткнення, весь хеш-ланцюг призведе до зіткнення ( незалежно від того, які інші хеші в ланцюжку ).

Сильніший ланцюг був би

hash1(hash2(hash3(...hashn(pass + salt) + pass + salt) + pass + salt)...) + pass + salt)

Тут ми уникаємо проблеми раннього зіткнення і по суті виробляємо сіль, яка залежить від пароля для остаточного хешу.

І якщо один крок у ланцюзі зіткнеться, це не має значення, оскільки на наступному кроці пароль буде використаний знову і повинен дати різний результат для різних паролів.


Отож зараз я бачу, що додавання "пароль + сіль" як солі до наступного раунду хешування може збільшити кількість "речей", які можуть потрапити у воронку, тепер я просто маю розуміти під "скільки". Дякую.
Нарцис

Насправді я думаю, що це я отримую зараз: примушуючи пароль в кожному шарі хешування, чи фактично зменшується кількість можливих зіткнень, по суті вимагаючи «пароль, що стикається» та реальний пароль, щоб мати відповідні хеші для кожного «виклику» , правда? Я думаю, що мені не вистачало частини "ввести пароль у кожному шарі"! Знову дякую.
Нарцис

@Narcissus не має жодних проблем, і це також має бонус за надання більш слабких внутрішніх хешей (до тих пір, поки зовнішні / кінцеві хеші будуть сильними), оскільки внутрішні хеши просто генерують сіль для наступного проходу
храповика з урожаю

гум, я думаю, що проблема трохи більша (і глибша), ніж ця. За допомогою райдужних атак ви можете просто генерувати таблиці, враховуючи всі ваші хеші, і проблема залишається.
woliveirajr

4
@Narcissus: дуже коротка відповідь: Так, це не більш безпечно. Так, напевно, це ще менш безпечно.
woliveirajr

54

Використання різних алгоритмів хешування - це погана ідея - це скоротить ентропію, а не збільшить її.

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

Останні алгоритми хешування, такі як bcrypt, ґрунтуються на цій ідеї; вони містять параметр для управління складністю хешу обчислювальної техніки, щоб ви могли масштабувати його в міру прогресування апаратних швидкостей: коли апаратне забезпечення стає швидше в два рази, ви збільшуєте складність для компенсації, тому потрібен час, щоб примусити грубу силу хеші залишаються приблизно постійними.


2
Це правильна відповідь!
Маркус

@markus: згідно з обговорюваною нами дискусією, це правильно лише через додавання "і гарної солі", на яке посилається прийнята відповідь, чи не так? Чому це одна правильна і прийнята відповідь - ні?
Нарцис

Це правильна відповідь, тому що єдиною причиною застосування однієї і тієї ж функції хешування кілька разів (параметризовано) є те, що ви можете використовувати цю ітерацію для налаштування більш швидкого обладнання. В іншому випадку від хешування не буде користі.
Маркус

@Narcissus Ключовим тут є ентропія. Існує різниця між хешуваннями багато разів, використовуючи один і той же метод, порівняно з хешированием багато разів, використовуючи різні методи.
sakisk

3

Не намагайтеся написати власну схему хешування паролів, якщо ви не бажаєте пройти курс криптографії та / або інженерії безпеки.

Вам слід використовувати чітко встановлену реалізацію хешування паролів, яка, в свою чергу, повинна використовувати функцію виведення ключа ( KDF ), наприклад PBKDF2, bcrypt, scrypt або новіший Argon2.

Хороші KDF включають робочий фактор, як правило, ряд ітерацій, щоб підвищити вартість офлайн-атак. Можна сказати, що ці KDF хешують пароль кілька разів, використовуючи один і той же алгоритм кожен раз. Немає сенсу використовувати алгоритм перебору декількох повідомлень, як вказували інші.


1
посилання https://crackstation.net/hashing-security.htm заблоковано брандмауером
gnat

1
@gnat Чомусь я пропустив ваш коментар щодо заблокованої URL-адреси. Я замінив це посиланням на wikipedia.
Ерван Легранд

2

Загалом, вам не потрібно використовувати більше ніж один алгоритм хешування.

Що вам потрібно зробити:

Використовуйте сіль: сіль не використовується лише для того, щоб зробити ваш пароль більш безпечним , вона використовується для відмови від атаки на райдужну таблицю. Таким чином, комусь доведеться посилити роботу, намагаючись попередньо обчислити хеш для паролів, які ви зберігаєте у вашій системі.

Використання декількох interations: замість того, щоб робити тільки SHA (пароль + сіль), зробіть SHA (SHA (SHA (SHA (SHA (... SHA (пароль + сіль)))))). Або представити іншим способом:

hash = sha(password + salt)
for i=1 , i=5000, i++ {
    hash = sha(hash + salt);
}

І, нарешті, виберіть хорошу функцію хешування. SHA, MD5 тощо не є хорошими, оскільки вони занадто швидкі . Оскільки ви хочете використовувати хеш для захисту, краще використовувати повільні хеші. Погляньте, наприклад, на Bcrypt , PBKDF2 або Scrypt .

редагувати : після спостережень давайте спробуємо побачити деякі моменти (вибачте, довге пояснення, щоб дійти до кінця, оскільки це може допомогти іншим шукати подібні відповіді):

Якщо ваша система захищена, як ніхто ніколи не отримає доступ до збереженого пароля, вам не потрібен хеш. Пароль був би секретним, його ніхто не отримає.

Але ніхто не може запевнити, що база даних із паролями буде вкрадена. Викрали базу даних, отримали всі паролі. Гаразд, ваша система та ваша компанія понесуть усі наслідки. Отже, ми могли б спробувати уникнути протікання цього пароля.

Зверніть увагу, що нас не турбують інтернет-атаки. Для однієї атаки в Інтернеті найкращим рішенням є гальмування помилкових паролів, блокування облікового запису після деяких спроб і т. Д. І для цього не важливо, в який спосіб ви шифруєте, хешуєте, зберігаєте тощо свій пароль. Інтернет-атака - це питання сповільнення введення пароля .

Отже, повернемося до don't let them take my plain passwordsпроблеми. Відповідь проста: не зберігайте їх як звичайний текст. Добре, зрозумів.

Як цього уникнути?

Зашифруйте пароль (?). Але, як відомо, якщо ви зашифруєте його, ви можете розшифрувати його назад, якщо у вас є належний ключ. І у вас виникне проблема "куди сховати" ключ. Гум, нічого доброго, оскільки вони отримали вашу базу даних, вони можуть отримати ваш ключ. Гаразд, не будемо ним користуватися.

Отже, ще один підхід: давайте перетворимо пароль у щось інше, що неможливо змінити і зберегти. І щоб переконатися, що наданий пароль правильний, ми знову робимо той самий процес і перевіряємо, чи відповідають ці два перетворені значення. Якщо вони відповідають = хороший пароль був наданий.

Добре, поки що добре. Давайте в паролі використаємо хеш MD5. Але ... якщо хтось має збережене хешоване значення пароля, у нього може бути багато комп’ютерної потужності, щоб обчислити хеш MD5 кожного можливого пароля (груба сила), тому він може знайти оригінальний пароль. Або, що ще гірше, він може зберігати весь MD5 з усіх комбінацій символів та легко знаходити пароль. Отже, зробіть багато ітерацій, HASH (HASH (HASH ())), щоб зробити це складніше, тому що це займе більше часу.

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

Отже, давайте використати трохи солі над цим. Таким чином, при кожній взаємодії сіль використовується знову. Кожен, хто намагається атакувати ваші паролі, повинен створити таблицю веселки, враховуючи, що сіль додається щоразу. І коли він генерує цю таблицю веселки, оскільки вона була створена з однією сіллю, йому доведеться знову обчислити з іншою сіллю, тому йому доведеться витратити деякий час на кожен пароль (= кожна сіль). Сіль не додасть «більшої складності» паролю, це просто змусить зловмисника втратити час, створюючи таблицю веселки, якщо ви використовуєте одну сіль для кожного пароля, стіл з однієї солі марний іншим паролем.

І використання більше одного хеша допоможе тут? Ні. Людина, яка генерує певну атаку веселки, у будь-якому випадку зможе генерувати її за допомогою одного або декількох хешей.

І використання більше одного хешу може призвести до однієї проблеми: це так само безпечно, як і найслабший хеш, який ви використовуєте. Якщо хтось знайде зіткнення в одному алгоритмі хешу, саме той хеш буде використаний в будь-якій точці процесу ітерації, щоб зламати пароль. Отже, ви нічого не отримуєте, використовуючи більше алгоритмів хешей, краще вибрати лише один хороший альго. і використовувати його. І якщо ви коли-небудь почуєте, що це було порушено, подумайте, як ви це зміните у своїй заяві.

І навіщо використовувати bcrypt чи щось подібне (ви кажете, що ви його використовуєте): тому що зловмиснику доведеться витрачати більше часу на створення таблиць. Ось чому використання MD5 + зачекання (3 секунди) не допомагає: атака все одно буде відключена, тому зловмисник може генерувати таблиці без (затримки на 3 секунди).


2
На жаль! Вибачте, мій коментар (про те, що навмисно робити хеш повільніше через параметр таймауту) не мав на увазі сприйматись серйозно ... Я думаю, що останнім часом я читав занадто багато Ділберта.
FrustratedWithFormsDesigner

2
sha (sha (sha (..))) не є більш безпечним, ніж sha. Якщо ентропія функції sha не максимальна, це насправді менш безпечно.
deadalnix

1
@deadalnix: важливо зазначити, що це не полегшує відновлення оригінального пароля, але робить його простіше генерувати збірний пароль, який є всім, що потрібно.
Брайан Боттчер

1
@deadalnix, я читав цей коментар голосом Дейла Гріббла .
джиггі

1
@deadalnix: мета sha (sha (sha ())) не є і ніколи не була, щоб додати більше ентропії. Ентропію якраз робить початковий користувач, обираючи свій пароль, все інше (хеш, сіль тощо) - це лише для уповільнення жорстокої атаки. Якщо хтось зможе отримати вашу базу даних, що містить паролі, він, ймовірно, отримає код, який використовується також для хешування пароля, тому будь-яка твердо кодована сіль також відома
woliveirajr

-1

Я розумію, що використання декількох алгоритмів хешування - перемогти веселкові таблиці . Використання хорошої солі також працює, але я думаю, що це другий рівень захисту.


4
Ну, це не так сильно зміниться. Fucntion «множинного хешу» може розглядатися як один і розглядатись як такий.
deadalnix

2
Використання декількох методів хешування або ітерацій не робить нічого для перемоги веселкових таблиць. Якщо зловмисник має вашу базу даних і має метод, який використовується для створення хешів, зловмисник може генерувати таблицю веселки для атаки на всі паролі в базі даних. СОЛТИ запобігають атакам райдужної таблиці, оскільки вони заважають зловмиснику створювати єдиний словник пошуку для атаки, скажімо, всіх паролів з 8 символів або менше.
Ерік

-1

Це не більш безпечно. Однак у вас є протокол ідентифікації, заснований на хеші кілька разів з однаковою функцією.

Це йде таким шляхом. Збережене значення має хеш ^ n (пропуск) у комп’ютері А. Попросити B підтвердити автентифікацію та надає B ціле число n. B робить обчислення хеш ^ (n-1) (пропуск) і відправляє його назад до A.

Перевірка, що хеш (хеш ^ (п-1) (пропуск)) == хеш ^ н (пропуск). Якщо це правда, то автентифікація робиться. Але тоді, хеш-магазин ^ (n-1) (пропуск) і наступна автентифікація дадуть B n-1 замість n.

Це гарантує, що пароль ніколи не змінюється чітко, що A ніколи не знає, що таке пароль, і що автентифікація захищена від повторного відтворення. Однак це недолік вимагає пароля з обмеженим терміном експлуатації. Коли n досягне значення 2, після автентифікації повинен бути обраний новий пароль.

Ще одне використання декількох хешів - це інструмент HMAC для забезпечення автентифікації та цілісності запиту. Більше про HMAC див . На веб-сайті http://en.wikipedia.org/wiki/HMAC .

Більшість використання кількох хешів у реальному світі є надмірними. У вашому випадку, мабуть, так і є. Зауважте, що якщо ви використовуєте кілька хеш-функцій, вони не будуть мати однакову ентропію, таким чином, це зменшить силу хеша. Для прикладу, md5 має меншу ентропію, ніж sha1, тому використання sha1 на md5 не покращить силу хешу. Сила, як правило, дорівнює силі слабшої хеш-функції.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.