Цей розділ пояснює причини використання геш-функцій для убезпечення паролів, а також, як це зробити ефективно.
Навіщо гешувати користувацькі паролі?
Гешування паролів є основним захисним заходом, що вживається під час розробки програми або сервісу, що приймає паролі від користувачів. Без гешування будь-які збережені паролі можуть бути вкрадені, якщо сховище даних зламають, та негайно використані для зламу програми чи сервісу і облікових записів користувачів у інших сервісах, де використано такі ж паролі.
Застосування алгоритму гешування користувацьких паролів перед збереженням унеможливлюєте викриття зловмисником оригінального пароля, маючи при тому змогу у майбутньому порівнювати отриманий геш з наявним.
Важливо підкреслити, що гешування паролів лише захищає їх від розкриття у сховищі даних, але не від перехоплення зловмисним кодом, вживленим у програму або сервіс.
Чому такі поширені геш-функції як md5() і sha1() не придатні для паролів?
Алгоритми гешування MD5, SHA1 та SHA256 розроблені бути дуже швидкими та
ефективними. З сучасною технікою та комп'ютерним обладнанням стало
легко зламати
результат цих алгоритмів, щоб визначити
початковий текст.
Через те, як швидко сучасні комп'ютери можуть запустити такий алгоритм
у зворотньому напрямку
, багато фахівців з безпеки
наполягають не використовувати таке гешування.
Як гешувати паролі, якщо поширені геш-функції не придатні.
Під час гешування паролів двома найважливішими факторами є витрати на обчислення та т. зв. "сіль". Чим більше обчислень має виконати алгоритм, тим довше триватиме злам результату його обчислень.
PHP має вбудований API гешування паролів, який надає засоби як гешування, так і перевірки паролів безпечним способом.
Для гешування паролів рекомендується алгоритм Blowfish, який стандартно використовується API гешування паролів, оскільки він є набагато дорожчим в обчисленні, аніж MD5 або SHA1, залишаючись масштабованим.
Функція crypt() також може гешувати паролі, але рекомендовано використовувати її тільки для підтримки сумісності з іншими системами. Натомість краще використовувати вбудований API гешування паролів за будь-якої можливості.
Що таке "сіль"?
Криптографічна сіль — це текст, який дописується до даних у процесі гешування, щоб унеможливити пошук результатів у списку попередньо обчислених пар гешів та їхніх вхідних даних, відомого як райдужна таблиця.
Простими словами, сіль — це допоміжна частинка даних, яка значно ускладнює злам ваших гешів . Існує певна кількість онлайн сервісів з надання розширених списків попередньо обчислених гешів, а також їхніх вхідних даних. Використання солі робить малоймовірним або неможливим знаходження отриманого гешу в одному з цих списків.
password_hash() створить випадкову сіль, коли та не вказана, і це, як правило, найпростіший і найбезпечніший підхід.
Де сіль зберігається?
У password_hash() або crypt() значення, що повертається, містить сіль як частину утвореного гешу. Це значення потрібно точно зберігати у базі даних, оскільки воно містить інформацію про геш-функцію, яка використовувалася, і потім може бути передано безпосередньо до функції password_verify() для перевірки паролів.
Задля убезпечення від часових атак потрібно завжди використовувати функцію password_verify() замість повторного гешування і порівняння результату зі збереженим гешем.
Наступна діаграма показує формат значення, що повертається функціями crypt() або password_hash(). Помітно, що значення є самодостатнім, з усією інформацією про алгоритм і сіль, необхідну для майбутньої перевірки пароля.