ВІДМОВА : Ця відповідь була написана у 2008 році.
З тих пір PHP надав нам password_hash
і password_verify
, з моменту їх введення, вони є рекомендованим методом перемішування та перевірки паролів.
Теорія відповіді все ще добре прочитана.
TL; DR
Не треба
- Не обмежуйте, які символи користувачі можуть вводити для паролів. Це роблять лише ідіоти.
- Не обмежуйте довжину пароля. Якщо ваші користувачі хочуть, щоб вирок із суперкаліфрагілісткоюxpialidocious в ньому не перешкоджав їх використанню.
- Не знімайте і не уникайте HTML та спеціальних символів у паролі.
- Ніколи не зберігайте пароль свого користувача в простому тексті.
- Ніколи не надсилайте електронної пошти пароль своєму користувачеві, за винятком випадків, коли він втратив їх, і ви надіслали тимчасовий.
- Ніколи, ніколи не реєструйте паролі будь-яким чином.
- Ніколи не хешуйте паролі з SHA1 або MD5 або навіть SHA256! Сучасні сухарики можуть перевищувати 60 і 180 мільярдів хеш / секунду (відповідно).
- Чи не слід змішувати Bcrypt і з сирим виходом хеш () , або використовувати шістнадцятковий вихід або base64_encode його. (Це стосується будь-якого входу, у якого може бути шахрай
\0
, який може серйозно послабити безпеку.)
Дос
- Використовуйте скріпт, коли можете; bcrypt, якщо ви не можете.
- Використовуйте PBKDF2, якщо ви не можете використовувати ні bcrypt, ні scrypt, з хешами SHA2.
- Скиньте всі паролі, коли база даних порушена.
- Реалізуйте розумну мінімальну довжину 8-10 символів, плюс потрібно щонайменше 1 верхню літеру, 1 малу літеру, цифру та символ. Це поліпшить ентропію пароля, у свою чергу зробивши його складніше. (Див. Розділ «Що робить гарний пароль?» Для дебатів.)
Навіщо взагалі хеш-паролі?
Завдання хешування паролів проста: запобігання зловмисному доступу до облікових записів користувачів шляхом компрометації бази даних. Таким чином, мета хешування паролів полягає у відлякуванні хакера чи злому, витративши їм занадто багато часу чи грошей на обчислення простотекстових паролів. А час / вартість - найкращі засоби стримування у вашому арсеналі.
Ще одна причина, що ви хочете отримати хороший, надійний хеш на облікових записах користувачів, - це дати вам достатньо часу для зміни всіх паролів у системі. Якщо ваша база даних порушена, вам знадобиться достатньо часу, щоб принаймні заблокувати систему, якщо не змінити кожен пароль у базі даних.
Єремія Гроссман, генеральний директор Whitehat Security, заявив на блозі White Hat Security після недавнього відновлення пароля, що вимагало злому злому захисту його паролем:
Цікаво, що, переживаючи цей кошмар, я дізнався багато, що я не знав про зламування паролів, зберігання та складність. Я зрозумів, чому зберігання паролів завжди набагато важливіше, ніж складність пароля. Якщо ви не знаєте, як зберігається ваш пароль, то все, від чого ви дійсно можете залежати, - це складність. Це може бути загальновідомим паролем і криптовалютами, але для пересічного експерта InfoSec або веб-безпеки я дуже сумніваюся в цьому.
(Наголос мій.)
Що робить гарний пароль все-таки?
Ентропія . (Не те, щоб я повністю підписався на точку зору Рандалла.)
Коротше кажучи, ентропія - це кількість варіацій пароля. Якщо паролем є лише малі римські літери, це лише 26 символів. Це не велика різниця. Альфа-цифрові паролі краще, з 36 символами. Але допустимий верхній і нижній регістр із символами становить приблизно 96 символів. Це набагато краще, ніж просто листи. Одна проблема полягає в тому, щоб зробити наші паролі запам'ятовуючими, ми вставляємо шаблони, що зменшує ентропію. На жаль!
Пароль ентропія наближена легко. Використання повного діапазону символів ascii (приблизно 96 символів, що набираються) дає ентропію 6,6 на символ, що на 8 символів для пароля все ще занадто низьке (52,679 біт ентропії) для подальшої безпеки. Але гарна новина полягає в тому, що довші паролі та паролі з символами unicode дійсно збільшують ентропію пароля і ускладнюють його зламати.
На сайті Crypto StackExchange триваліше обговорюється ентропія паролів . Хороший пошук в Google також дасть багато результатів.
У коментарях я спілкувався з @popnoodles, який вказував, що застосування політики паролів довжиною X з багатьма літерами, цифрами, символами тощо може насправді зменшити ентропію, зробивши схему паролів більш передбачуваною. Я згоден. Випадкова випадкова ситуація - це найбезпечніше, але найменш запам'ятоване рішення.
Наскільки я міг сказати, зробити найкращий у світі пароль - це Catch-22. Або його не запам'ятоване, занадто передбачуване, занадто коротке, занадто багато символів однокодування (важко набрати на пристрої Windows / Mobile), занадто довге тощо. Жоден пароль не є справді достатнім для наших цілей, тому ми мусимо захищати їх так, ніби вони були у Форт-Нокс.
Кращі практики
Bcrypt та scrypt - це поточні найкращі практики. Scrypt буде кращим, ніж bcrypt в часі, але він не бачив прийняття в якості стандарту Linux / Unix або веб-серверами, і ще не опублікував глибоких оглядів свого алгоритму. Але все-таки майбутнє алгоритму виглядає перспективно. Якщо ви працюєте з Ruby, є дорогоцінний камінь, який допоможе вам, і Node.js тепер має власний пакет скриптів . Ви можете використовувати Scrypt в PHP через розширення Scrypt або розширення Libsodium (обидва доступні в PECL).
Я настійно пропоную прочитати документацію для функції криптів, якщо ви хочете зрозуміти, як використовувати bcrypt, або знайти собі хорошу обгортку або використати щось на зразок PHPASS для більш застарілої реалізації. Я рекомендую мінімум 12 раундів bcrypt, якщо не 15-18.
Я змінив свою думку щодо використання bcrypt, коли дізнався, що bcrypt використовує лише ключовий графік, що застосовується, із механізмом змінної вартості. Останнє дозволяє збільшити витрати на жорстоку силу пароля, збільшивши вже дорогий ключовий графік.
Середня практика
Я вже майже не можу уявити цю ситуацію. PHPASS підтримує PHP 3.0.18 до 5.3, тому його можна використовувати майже на будь-якій можливій установці - і його слід використовувати, якщо ви точно не знаєте, що ваше середовище підтримує bcrypt.
Але припустимо, що ви взагалі не можете використовувати bcrypt або PHPASS. Що тоді?
Спробуйте впровадити PDKBF2 з максимальною кількістю раундів, які може сприйняти ваше оточення / програма / сприйняття користувача. Найнижча кількість, яку я рекомендував би, - 2500 патронів. Також переконайтеся, що він використовує hash_hmac (), якщо він доступний, щоб ускладнити відтворення операції.
Майбутні практики
Прихід у PHP 5.5 - це повна бібліотека захисту паролів, яка дозволяє усунути будь-які болі в роботі з bcrypt. Хоча більшість із нас застрягли з PHP 5.2 та 5.3 у більшості поширених середовищ, особливо спільних хостів, @ircmaxell створив рівень сумісності для API, що підтримується назад, сумісного з PHP 5.3.7.
Резюме криптографії та відмова від відповідальності
Обчислювальна потужність, необхідна для фактичного злому хешованого пароля, не існує. Єдиний спосіб комп'ютерів "зламати" пароль - це відтворити його та імітувати алгоритм хешування, який використовується для його захисту. Швидкість хешу лінійно пов'язана з його здатністю бути змушеною. Що ще гірше, більшість хеш-алгоритмів можна легко паралелізувати для виконання навіть швидше. Ось чому такі важливі дорогі схеми, як bcrypt та scrypt.
Ви не можете передбачити всі загрози або способи нападу, і тому ви повинні докласти максимум зусиль, щоб захистити своїх користувачів наперед . Якщо цього не зробите, то, можливо, навіть пропустите той факт, що на вас напали, поки не пізно ... і ви несете відповідальності . Щоб уникнути такої ситуації, почніть діяти параноїчно. Нападайте на власне програмне забезпечення (внутрішньо) та намагайтеся вкрасти облікові дані користувачів або змінити акаунти інших користувачів або отримати доступ до їх даних. Якщо ви не перевіряєте безпеку своєї системи, ви не можете звинувачувати нікого, крім себе.
Нарешті: я не криптограф. Що б я не сказав, це моя думка, але я думаю, що це засноване на здоровому здоровому глузді ... і багато читанні. Пам’ятайте, будьте максимально параноїчні, зробіть речі максимально важкими для втручання, а потім, якщо ви все ще переживаєте, зверніться до хакера з білими капелюшками або криптографом, щоб побачити, що вони кажуть про ваш код / систему.