Зберігання паролів в web-додатку
Існує багато прикладів і матеріалів, в яких показано як зберігати паролі в базі даних.
Часто описані методи неякісні і схильні до злому. У мережі є багато навчальних прикладів, які показують, як зробити це невірно.
На практиці, системи, які використовують доступ до даних по паролю жодним чином не повинні покладатися на те, що користувач создат "складний" пароль, наприклад, при реєстрації. "Складний" пароль для зловмисника, а не для користувача. Також помилково вважати свою систему на стільки захищеною і безпечною, що зловмисник не зможе отримати дамп таблици або файл з паролями або їх хешамі. З цього випливає, що потрібно щоб навіть при отриманні такого дампа, зловмисник нічого не міг з ним зробити, то є інформація була марна для нього.
Дуже поширена помилка це швидкі хеші. Наприклад, MD5 - дуже швидкий алгоритм хешування, втім як і всі SHA алгоритми. Наприклад, на NVIDIA GeForce 8800 можна генерувати 200 мільйонів MD5 хеш в секунду. З цього випливає, що використання швидких алгоритмів хешування, навіть з домішкою "солі" неефективне. Звичайним перебором можна порівняно швидко підібрати хеш, а відповідно і пароль користувача. З цього систему зі зберіганням паролів у вигляді md5 ( "password") - можна вважати відкритою для зловмисника.
Наприклад, на сервері для обчислення одного хеша використовуючи алгоритм md5, в середньому, потрібно 10мксек. Пароль зберігається у базі даних, як хеш від введеного значення користувача (md5 ( "password")). Зловмисник якимось чином отримав базу логінів з хешамі паролів і намагається розшифрувати їх. Алгоритм розшифровки найпростіший - перебір. Зрозуміло що для обчислення тисячі хешів потрібно 10мксек * 1000 = 10мсек, для мільйона 10мксек * 1000000 = 1 сек і т.д. З цього випливає, що чим швидше алгоритм хешування, тим швидше зловмисник підбере більше кількість паролів за менший проміжок часу. З вищесказаного санів ясним, що чим повільніше алгоритм обчислення хеш функції, тим надійніше.
Blowfish - криптографічний алгоритм, який реалізує блочне симетричне шифрування. Споживає порівняно велика кількість обчислювальних ресурсів і в даний час вважається досить непоганим алгорімом для шифрування паролів. У PHP реалізція доступна простим викликом crypt (). Подобор вагового параметра проводиться таким чином, що б атака перебором була досить повільна, а обчислення хешу для користувача непомітним за часом. 200-300 мсек на продакшн сервері цілком достатньо для цього.
Для більш стійкого хешу додають сіль. Сіль - слово, фраза, рандомноє значення температури, динамічне изминения чого або, яке додається довільно для формування кінцевого хешу. Наприклад, md5 ($ password. Md5 ($ salt)). З кожного пароля повинен формуватися хеш з унікальною сіллю. Мета добавлненія солі - збільшення розміру словника для атаки типу перебір по словнику або для райдужних таблиць. Сіль, яка використовується разом з Blowfish, що не об'язательно повинна бути криптографічного стійкою випадкової рядком. Досить використовувати сіль з псевдовипадкових чисел, цього достатньо для запобігання підбору пароля по райдужним таблицями.
При теперішніх ресурсах комп'ютерних систем скрость підбору пароля, використовуючи перебір, стає все швидше. Якщо ваше програмне забезпечення все ще використовує старі алгоритми хешування паролів, можливо є сенс задуматися про зміну цього алгоритму.
Використання crypt () в PHP для зберігання паролів
crypt () повертає хешірованного рядок, отриману за допомогою стандартного алгоритму UNIX, заснованого на DES, або іншого алгоритму, наявного в системі.
Сіль визначається в залежності від методу хешування. Для Blowfish-шифрування, формат такої: "$ 2a $", ваговій параметр з двох цифр, "$" і 22 цифри з алфавіту "./0-9A-Za-z". Використання інших символів в солі спричинить за собою повернення порожнього рядка. Ваговій параметр з двох цифр є двійковим логарифмом лічильника ітерацій низлежащего хешірующего алгоритму, заснованого на Blowfish, і повинен бути в діапазоні 04-31, значення поза даного діапазону викличуть відмова crypt (). наприклад:
Зверніть увагу, що перші 29 символів повернутого значення такі ж, як сіль.
При додаванні чого або в сіль результат не змінить:
І відповідно, якщо результат виконання функції crypt подати на вхід як сіль, для однієї і тієї ж рядки, то результатом виконання буде та ж сіль:
Принципи збереження пароля спільно з crypt:
- в сховище записуємо тільки хеш пароля і сіль, пароль явно не вказуємо;
- значення, що повертається виконанням функції crypt - це сіль з хешом;
- crypt ігноріоует зайві символи в рядку солі;