Невипадкова сіль для хешування паролів


89

ОНОВЛЕННЯ: Нещодавно з цього запитання я дізнався, що в усьому обговоренні нижче я (і я впевнений, що і інші) був трохи заплутаним: те, що я продовжую називати райдужним столом, насправді називається хеш-таблицею. Веселкові столи - це більш складні істоти, і насправді вони є різновидом Hellman Hash Chains. Хоча я вважаю, що відповідь все та ж (оскільки справа не зводиться до криптоаналізу), деякі обговорення можуть бути дещо перекошеними.
Питання: " Що таке райдужні столи і як вони використовуються? "


Як правило, я завжди рекомендую використовувати криптографічно сильну випадкову величину як сіль, для використання з хеш-функціями (наприклад, для паролів), наприклад, для захисту від атак Rainbow Table.

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


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


Дякую всім за відповіді на даний момент, але я хотів би зосередитись на областях, які (трохи) мені менш відомі. В основному це має наслідки для криптоаналізу - я був би дуже вдячний, якщо хтось має якийсь внесок від крипто-математичного PoV.
Крім того, якщо є додаткові вектори, які не враховувались, це теж чудово (див. Пункт @Dave Sherohman на декількох системах).
Окрім цього, якщо у вас є якась теорія, ідея чи найкраща практика - підкріпіть це будь-якими доказами, сценарієм нападу або емпіричними доказами. Або навіть обгрунтовані міркування щодо прийнятних компромісів ... Я знайомий з Передовою практикою (велика буква В) з цього питання, я хотів би довести, яку цінність це насправді надає.


РЕДАГУВАТИ: Тут є дійсно хороші відповіді, але я думаю, як каже @Dave, це зводиться до Веселкових таблиць для загальних імен користувачів ... і можливих менш поширених імен теж. Однак що, якщо мої імена користувачів є глобально унікальними? Не обов’язково унікальний для моєї системи, але для кожного користувача - наприклад, електронна адреса.
Не було б стимулу будувати RT для одного користувача (як підкреслював @Dave, сіль не тримається в таємниці), і це все одно запобігало б кластеризації. Єдина проблема полягала б у тому, що у мене можуть бути однакові адреси електронної пошти та пароль на іншому сайті - але сіль все одно не завадить цьому.
Отже, це зводиться до криптоаналізу - необхідна ентропія чи ні? (Зараз я думаю, що це не потрібно з точки зору криптоаналізу, а з інших практичних причин).


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

Якщо сіль потрібна, наприклад. сайту, у вас часто є ідентифікатори в URL-адресах. Якщо зловмисник знає (і ми припускаємо, що він знає), що пароль солі - це ідентифікатор користувача + ім'я користувача, досить легко змінити атаку, щоб уникнути значення солі.
dmajkic

@dmajkic, сіль призначена для запобігання RT-атакам та диференціації однакових паролів для різних користувачів. Це дане, навіть з іменами користувачів.
AviD

@AviD: Це правда. Але якщо я знаю свій хеш для мого пропуску, і я знаю, що salt - це моє ім’я користувача, я можу легко створити хешоване значення проходу для будь-якого словникового слова та порівняти його з іншим, хто передає хеш. Ось чому час кращий за ім'я користувача.
dmajkic

1
Щойно знайшов статтю на веб-сайті Консорціуму безпеки PHP, яка у своєму прикладі використовує випадкове число md5 у вигляді солі phpsec.org/articles/2005/password-hashing.html
helloworlder

Відповіді:


156

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

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

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

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

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

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

Причина важливості ентропії полягає у тому, щоб уникнути кластеризації значень солі. Якщо сіль базується на імені користувача, і ви знаєте, що у більшості систем буде обліковий запис з іменем "root" або "admin", тоді ви можете скласти райдужну таблицю для цих двох солей, і це зламає більшість систем. Якщо, з іншого боку, використовується випадкова 16-бітна сіль і випадкові значення мають приблизно рівномірний розподіл, то вам потрібна райдужна таблиця для всіх 2 ^ 16 можливих солей.

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


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

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

@AviD: Ти так думаєш? Це досить специфічний вектор атаки.
Девід Грант

2
Не для отримання солей, ні. Єдині атаки, на які впливає сіль, це атаки, зроблені безпосередньо на хешовані паролі. Атака не може здійснити такий вид атаки, якщо у них немає копії вашої бази даних паролів, яка також міститиме солі. Оскільки зловмисник вже має у своєму розпорядженні солі, вони вимагають лише достатньої ентропії, щоб уникнути хешування декількох паролів однією і тією ж сіллю, яку надасть будь-який базовий (P) RNG.
Dave Sherohman

3
@ acidzombie24: Використання однієї фіксованої солі (яку в моєму досвіді зазвичай називають "нонсом") для всіх паролів є менш безпечним, ніж використання унікальної випадкової солі для кожного пароля, оскільки це все одно дозволяє зловмисникові тривіально визначити, чи мають два або більше облікових записів спільний доступ той самий пароль. З іншого боку, nonce, швидше за все, буде зберігатися у вашому коді, а не в базі даних, тому зловмисник, який має лише вашу базу даних, не матиме до неї доступу; через це найбільш безпечним варіантом є використання як загальносистемного nonce (що зберігається в коді), так і солі для кожного пароля (що зберігається в базі даних).
Dave Sherohman

29

Використання солі з високою ентропією є абсолютно необхідним для надійного зберігання паролів.

Візьміть моє ім'я користувача 'gs' і додайте його до мого пароля 'MyPassword' дає gsMyPassword. Це легко зламати, використовуючи райдужну таблицю, тому що, якщо ім’я користувача не має достатньої ентропії, можливо, це значення вже зберігається в райдужній таблиці, особливо якщо ім’я користувача коротке.

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

Раніше вони мали 12-бітну сіль . 12 біт - це 4096 різних комбінацій. Це було недостатньо безпечно, оскільки сьогодні стільки інформації можна легко зберегти . Те саме стосується 4096 найпоширеніших імен користувачів. Цілком ймовірно, що деякі з ваших користувачів виберуть ім’я користувача, яке належить до найбільш поширених імен користувачів.

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


+1 за хороший момент, однак, буде говорити про потенційно масивному столі веселки. Щоб покрити всі значення довжини gsMyPassword (припускаючи, що буквено-цифрові змішані регістри), потрібно 36 ^ 12 рядків у таблиці!
Девід Грант,

Надалі: проект розподіленого райдужного столу має 63 970 тріщин хешів, але 36 ^ 12 - це 4738381.338.321.616.896!
Девід Грант,

Дякую, і це має сенс - але, як зазначив Mr.PotatoHead, ви все ще розширюєте свій простір за межі розумної можливості розтріскування за допомогою RT. Крім того, припускаючи, що мої імена користувачів мають щонайменше 6-8 символів - яке додаткове необхідне значення надає ентропія?
AviD

@ Картопля: ви припускаєте райдужну таблицю, що містить усі можливі комбінації буквено-цифрових символів. Це не обов’язково, ефективна таблиця веселки буде містити хеші для загальних паролів / хешів. Сіль існує для захисту від нападів на словники або комбінованого веселки / словника.
Гійом

3
Використання імені користувача як солі - це також погана ідея для систем, де існує передбачувана назва облікового запису із високими привілеями: "Адміністратор" у Windows, "root" у * nix, "sa" у MSSQL тощо
ніхто

8

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

хешфункція ("www.yourpage.com /" + ім'я користувача + "/" + пароль)

Це має вирішити проблему. Я не майстер криптоаналізу, але я впевнений, що той факт, що ми не використовуємо високу ентропію, зробив би хеш слабшим.


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

7

Мені подобається використовувати і те, і інше: високоентропійна випадкова сіль на запис, плюс унікальний ідентифікатор самого запису.

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

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


Мені подобається ідея прив’язки пароля до користувача. Але якщо зловмисник може змінити пароль, він, безсумнівно, може також змінити ідентифікатор.
Георг Шеллі

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

3
Ні, мені це подобається. Зловмисник часто є "інсайдером". Я міг би придумати сценарії, коли того, за чим він переслідує, немає в базі даних, але якщо він може перезаписати облікові дані в базі даних, він може автентифікувати себе, щоб робити те, що він хоче.
erickson

1
Гарна думка. Ми виявляємо, що ускладнює додавання першого користувача до нової бази даних: ми ефективно зробили наші програми настільки безпечними, що ледве можемо їх зламати самі. [Крім того, використовуйте специфічну сіль, щоб ви не могли копіювати облікові дані з однієї бази даних в іншу.]
teedyay,

Нарешті я знайшов когось, що сказав це: додавши щось особливе для користувача до солі. Це дозволяє уникнути зловмисника скопіювати деякі дані для іншого користувача, а також заважає хакеру вгадати будь-який пароль, якщо йому вдається зв’язати ваше поле хешу та солі в таблиці. Ще одне, що я люблю робити: не використовувати круглу кількість ітерацій у хешуванні. Не йдіть на 10 або 20 тисяч, а скоріше на щось на зразок 19835.
Ендрю

3

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

Використання унікальних солей підвищує складність атак зі словником BULK.

Ідеально мати унікальну, криптографічно сильну цінність солі.


2
Вся суть райдужної таблиці полягає в тому, що значення створюються заздалегідь, і якщо ви створюєте таблицю для значення (наприклад, пароля) ПЛЮС даної константи, це зовсім інша таблиця, і ви можете просто спробуйте результат хешу безпосередньо. :)
Девід Грант

1
Постійний хеш нічого не вартий. Усі паролі можна зламати за допомогою єдиної таблиці веселки. Призначення солі полягає в тому, що неможливо створити райдужний стіл.
Георг Шеллі

1
@gs - я не розумію, чому ти не можеш побудувати райдужну таблицю, яка "включає" ефекти постійної солі. Місце для атаки (пароль) не зміниться, тому таблиці не потрібно буде рости, просто перерахуйте.
HUAGHAGUAH

@ Картопля - залежить від компромісу. Якщо 20 тисяч входів вашої компанії хешували з однаковою незмінною кількістю солі, можливо, дешевше буде обчислити нову таблицю веселки, аніж словник атакувати їх усі окремо. Звідси мій наголос на "БАК".
HUAGHAGUAH

3

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

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


3
Msgstr "Суть солі в тому, що ви не можете використовувати стандартну таблицю веселки для розв'язання кожного пароля в базі даних". Я не погоджуюсь. Справа в тому, що ви не можете використовувати стандартну таблицю веселки, щоб вирішити будь-який пароль. Якщо сіль - це ім'я користувача, тоді райдужна таблиця для "кореня" може зламати pw кореня.
Steve Jessop

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

Це теж було моє мислення - але я застряг у "напевно добре". Я досі не бачу, щоб цю теорію доводили - або принаймні перевіряли, що ніяких наслідків криптоаналізу немає.
AviD

@onebyone: Якщо сіль складається з імені користувача + постійного місцевого значення (я часто використовую ':'), це все одно руйнує стандартизовані RT, якщо не існує різноманітних з них, що включають загальні імена користувачів та загальні статичні значення солі. Я швидше підозрюю, що це не так.
nsayer

Поряд з nsayer. Ви можете використовувати загальносистемний константний рядок, щоб не існувало попередньо сформованого RT, наприклад, # (D83d8, разом з іменем користувача як солі, і це може запобігти будь-яким атакам райдужної таблиці.
Kibbee

3

Сила хеш-функції не визначається її введенням!

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

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

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

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


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

@Martin: Єдине, що ви зможете вивести з хеш-значення, якщо у вас є збіг чи ні! Поміщення "roota" або "rootb" (де "a" і "b" представляють пароль) у хеш-функцію дасть вам кардинально різні результати.
Девід Грант,

Солі відомі зловмиснику за допомогою райдужних столів.
Георг Шеллі

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

Правильно, правильно, це дано - якщо бути більш конкретним, я мав на увазі силу загальної криптосистеми (або -підсистеми, wrt-хеші).
AviD

1

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

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

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

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


Знову ж таки, я не маю на увазі використання однієї константної солі - скоріше невипадкове, але унікальне для користувача значення. Наприклад, ідентифікатор користувача.
AviD

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

-1

Ентропія є точкою значення Солі.

Якщо за сіллю стоїть якась проста і відтворювана "математика", це все одно, що солі немає. Просто додавання значення часу повинно бути нормальним.


Я не розумію цей коментар. Ви кажете "використовувати ентропію", а потім: "використати час" ??
Мартін Карпентер

якщо ім’я користувача використовується для солі, це „недостатньо ентропійно. Але якщо ви використовуєте ім'я користувача + поточний час - це так, оскільки важко здогадатися, коли саме була створена сіль.
dmajkic

"досить ентропійний" суб'єктивний; це ваш стандарт. Встановлення цього значення вчасно може бути недостатнім.
Мартін Карпентер,

Не існує такого поняття, як "абсолютна справжня випадковість". Ми повинні сказати, коли це "досить добре". Якщо ви вважаєте, що в цьому випадку час недостатньо хороший, використовуйте щось інше. stackoverflow.com/questions/84556 / ...
dmajkic

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