Який тип даних використовувати для хешованого пароля та яку довжину?


268

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

Я думаю про обмеження паролів 4-20 символами, але, як я розумію, після шифрування хеш-рядка буде різної довжини.

Отже, як зберігати ці паролі в базі даних?


Також дивіться рамку хешування паролів PHP Openwall (PHPass). Його портативний та загартований проти низки поширених атак на паролі користувачів. Хлопець, який написав рамки (SolarDesigner) - той самий хлопець, який написав Джон The Ripper і сидить суддею в змаганнях з пароля . Тож він знає річ чи дві про атаки на паролі.
jww

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

чому обмежувати довжину пароля? Принаймні, дозвольте користувачеві створити пароль із 100 символів :)
Ендрю

4 символи - це досить небезпечна нижня межа для паролів, оскільки вони тріщинні. Принаймні використовувати 8, але 14 або 16 набагато краще.
quikchange

Це дуже старе запитання із застарілою відповіддю. Дивіться актуальну відповідь Жиля .
келалака

Відповіді:


448

Оновлення: просто використання хеш-функції недостатньо сильне для зберігання паролів. Ви повинні прочитати відповідь від Жилла на цій темі для більш детального пояснення.

Для паролів використовуйте алгоритм хешування для зміцнення ключів, як Bcrypt або Argon2i. Наприклад, у PHP використовуйте функцію password_hash () , яка використовує Bcrypt за замовчуванням.

$hash = password_hash("rasmuslerdorf", PASSWORD_DEFAULT);

Результат - рядок розміром 60 символів, подібний до наступного (але цифри будуть різними, оскільки він генерує унікальну сіль).

$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

Використовуйте тип даних SQL CHAR(60)для зберігання цього кодування Bcrypt хеша. Зверніть увагу, що ця функція не кодує як рядок шістнадцяткових цифр, тому ми не можемо так легко зняти її з шестидесятичного числа для зберігання у двійковій формі.

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


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

  • MD5 генерує 128-бітове хеш-значення. Ви можете використовувати CHAR (32) або BINARY (16)
  • SHA-1 генерує 160-бітове хеш-значення. Ви можете використовувати CHAR (40) або BINARY (20)
  • SHA-224 генерує 224-бітове хеш-значення. Ви можете використовувати CHAR (56) або BINARY (28)
  • SHA-256 генерує 256-бітове хеш-значення. Ви можете використовувати CHAR (64) або BINARY (32)
  • SHA-384 генерує 384-бітове хеш-значення. Ви можете використовувати CHAR (96) або BINARY (48)
  • SHA-512 генерує 512-бітове хеш-значення. Ви можете використовувати CHAR (128) або BINARY (64)
  • BCrypt генерує 448-бітне хеш-значення, що залежить від реалізації. Можливо, вам знадобиться CHAR (56), CHAR (60), CHAR (76), BINARY (56) або BINARY (60)

Станом на 2015 рік, NIST рекомендує використовувати SHA-256 або новіші версії для будь-яких застосувань хеш-функцій, що вимагають сумісності. Але NIST не рекомендує використовувати ці прості хеш-функції для безпечного зберігання паролів.

Менші алгоритми хешування використовують їх використання (як внутрішній додаток, а не для обміну), але вони, як відомо, є хитросплетеними .


47
@Hippo: Не використовуйте ім'я користувача як сіль. Створіть випадкову сіль на кожного користувача.
Білл Карвін

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

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

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

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

13

Ви можете фактично використовувати CHAR(довжина хеша) для визначення типу даних для MySQL, оскільки кожен алгоритм хешування завжди оцінюватиме однакову кількість символів. Наприклад, SHA1завжди повертає шістнадцяткове число у 40 символів.


1
SHA-1 не підходить для хешування паролів.
перестань бути злим"

10

Завжди використовуйте алгоритм хешування паролів: Argon 2 , Scrypt , Bcrypt або PBKDF2 .

Аргон2 виграв конкурс з шикування паролів 2015 року. Scrypt , Bcrypt і PBKDF2 старіші алгоритми, які вважаються менш привабливим в даний час, але до сих пір в основному звук, так що якщо ваша платформа не підтримує Argon- все ж, це нормально , щоб використовувати інший алгоритм зараз.

Ніколи не зберігайте пароль безпосередньо в базі даних. Не шифруйте це також: інакше, якщо ваш сайт буде порушений, зловмисник отримує ключ розшифровки і таким чином може отримати всі паролі. Паролі ОБОВ'ЯЗКОВО хешируются .

Хеш пароля має різні властивості з хеш - таблиці хеш або криптографічного хеш. Ніколи не використовуйте для пароля звичайний криптографічний хеш, такий як MD5, SHA-256 або SHA-512. Алгоритм хешування паролів використовує унікальну сіль (не використовується для будь-якого іншого користувача чи в базі інших даних). Сіль необхідна, щоб зловмисники не могли заздалегідь обчислити хеши загальних паролів: з сіллю вони повинні перезапустити обчислення для кожного облікового запису. Алгоритм хешування паролів по суті повільний - настільки повільний, як ви можете собі дозволити. Повільність шкодить зловмиснику набагато більше, ніж ви, тому що зловмиснику доводиться випробувати багато різних паролів. Щоб отримати додаткові відомості, див. Як надійно захистити паролі .

Хеш паролів кодує чотири відомості:

  • Індикатор, який алгоритм використовується. Це необхідно для спритності : криптографічні рекомендації змінюються з часом. Потрібно мати можливість переходу до нового алгоритму.
  • Індикатор складності або твердості Чим вище це значення, тим більше обчислень потрібно для обчислення хешу. Це має бути постійним або глобальним значенням конфігурації у функції зміни пароля, але воно повинно зростати з часом, оскільки комп'ютери стають швидшими, тому потрібно пам’ятати значення для кожного облікового запису. Деякі алгоритми мають одне числове значення, інші мають більше параметрів (наприклад, для налаштування використання процесора та використання оперативної пам’яті окремо).
  • Сіль. Оскільки сіль повинна бути унікальною у всьому світі, її потрібно зберігати для кожного облікового запису. Сіль повинна генеруватися випадковим чином при кожній зміні пароля.
  • Власний хеш, тобто вихід математичного обчислення в алгоритмі хешування.

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

$ алгоритм $ параметри $ сіль $ вихід

де algorithmчисло або коротка буквено-числова рядок, що кодує вибір алгоритму, parametersє друкованою рядком saltі outputкодуються в Base64 без закінчення =.

16 байт вистачає на сіль і вихід. (Див., Наприклад, рекомендації щодо Argon2 .) Зашифровано в Base64, це 21 символ. Дві інші частини залежать від алгоритму та параметрів, але 20–40 символів є типовими. Це загалом близько 82 символів ASCII ( CHAR(82)і Unicode немає необхідності), до яких слід додати запас безпеки, якщо ви думаєте, що згодом поле буде складно збільшити.

Якщо ви кодуєте хеш у двійковому форматі, ви можете зменшити його до 1 байта для алгоритму, 1–4 байта для твердості (якщо ви жорстко кодуєте деякі параметри), і 16 байт для солі та виводу , в цілому 37 байт. Скажіть, 40 байтів ( BINARY(40)) мають принаймні пару запасних байтів. Зауважте, що це 8-бітні байти, а не символи для друку, зокрема поле може включати нульові байти.

Зауважте, що довжина хеша абсолютно не пов'язана з довжиною пароля.


9

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


2
Це дійсно дуже варте (+1), але це не відповідає на питання! (-1)
Білл Карвін

3
Так, але безумовно актуально в цьому контексті (+1)
Treb

7

У якості рядка з фіксованою довжиною (VARCHAR (n) або як його називає MySQL). Хеш завжди має фіксовану довжину, наприклад, 12 символів (залежно від алгоритму хешу, який ви використовуєте). Так пароль 20 char буде зменшено до 12 char хеша, а 4 char char також призведе до 12 char хеша.


3
"або, як MySQL називає його" - MYSQL називає його CHAR. Цей тип призначений для значення фіксованої довжини. Тому я думаю, що CHAR є кращим типом, ніж VARCHAR.
t298712383

4

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


3

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


3

Хеші - це послідовність бітів (128 біт, 160 біт, 256 біт тощо, залежно від алгоритму). Ваш стовпець повинен бути двійковим, а не текстовим / символьним, якщо MySQL дозволяє (тип даних SQL Server є binary(n)або varbinary(n)). Також слід посолити хеши. Солі можуть бути текстовими або двійковими, і вам знадобиться відповідний стовпець.


Справедливість тут абсолютно коректна - MySQL зберігатиме їх як числові значення і зробить пошук у цьому стовпчику набагато ефективнішим, ніж збігання рядків, однак солі не повинні зберігатися в базі даних поруч із засоленими даними - це виключає безпеку, яку надають солі .
Тоні Маро

6
Солі не є секретом. Тільки секрет , є пароль. Просто переконайтеся, що кожен новий пароль отримує нову сіль. Щоразу, коли користувач змінює свій пароль, система повинна генерувати нову сіль для цього пароля. Солі повинні бути довгими і випадковими, наприклад, 16 байтами, згенерованими з криптографічно захищеного PRNG.
yfeldblum

1
@TonyMaro Не впевнений, чи відповідає відповідність строкової паролі на рівні SQL. Іншими словами, не слід шукати пароль у вашій базі даних, а замість цього отримати користувача на основі його імені користувача та порівняти паролі в коді, а не SQL.
барт

1

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


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