Чи варто хешувати паролі на стороні клієнта


132

Коли я хочу встановити систему входу, я завжди порівнюю MD5 даного пароля з його значенням у таблиці користувачів на стороні сервера.

Однак мій друг сказав мені, що «чіткий» пароль може обнюхати мережеве програмне забезпечення.

Отже, моє запитання: чи гарна ідея хешувати пароль на стороні клієнта? Це краще, ніж хешировать його на стороні сервера?


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

1
Просто для повноти, оскільки ми говоримо про безпеку, і MD5 згадувався в ОП: Завжди слід використовувати сіль при шифруванні пароля. Використання простого, несолоного MD5 просто незначно краще, ніж зберігання паролів прямого тексту у вашій базі даних.
sffc

1
@Cyclone Hashing ТІЛЬКИ на стороні клієнта, безумовно, погана ідея, оскільки якщо зловмисник якось знає хеш, він може використовувати його для входу, як якщо б він знав пароль, минаючи хешируючий хеш-код на стороні клієнта.
Teejay

5
@Teejay: Ось чому ви не надсилаєте хеш в чистоті. Сервер відправляє клієнту випадкову сіль, ви додаєте хеш пароля і знову хешируйте все, а потім відправляєте його назад на сервер, який робить той самий розрахунок. Атака повторного завершення не вдасться, оскільки сіль буде іншою
MSalters

2
Чи не повинно це питання закінчитися на security.stackexchange.com?
efr4k

Відповіді:


115

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

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

На сервері:

  • генерують кілька випадкових випадків
  • відправити ці біти (чітким текстом) клієнту

Про клієнта:

  • генерують кілька випадкових біт
  • об'єднати пароль, випадкові біти сервера та випадкові біти клієнта
  • генерувати хеш із перерахованого вище
  • подати випадкові біти (чітким текстом) та хеш на сервер

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

Редагувати Все це є схильним до помилок і стомлюючим, і дещо важко виправитись (читати: захистити) Якщо це можливо, подумайте про використання реалізацій протоколу аутентифікації, які вже написані знаючими людьми (на відміну від мене! Вище сказано лише з пам’яті книги, яку я прочитав деякий час тому.) Ви дійсно не хочете писати це зазвичай самі.


5
Як він може автентифікувати хешований пароль у системі входу, оскільки він буде повторно хешований?
Закарія

4
Якщо ви зберігаєте ваші паролі в хешованому вигляді на сервері (як слід), клієнт повинен буде хеш-код двічі: спочатку лише один пароль, щоб він відповідав погляду сервера на світ, а потім, як описано вище для заради протоколу.
Дірк

3
@Dirk, оскільки зловмисник може нюхати обома способами, "випадкові біти" будуть нюхати разом. Тоді зловмисник може проаналізувати (читати: груба сила) запит та пару відповідей в режимі офлайн, щоб знайти оригінальний пароль.
Pacerier

7
Однак для подання пароля або хешу пароля часто асиметричний процес на зразок Діффі-Хеллмана використовується для встановлення ключа шифрування, який дозволяє обом сторонам обмінюватися інформацією, не можучи сторону, що проглядається, розшифрувати її. Це саме те, що робить SSL, і це причина, що більшість сайтів мають свою сторінку входу на HTTPS / SSL. SSL вже захищає від атак відтворення. Я б рекомендував використовувати SSL, а не будувати власний протокол. Хоча я згоден із засолюванням + хешуванням клієнтської сторони пароля, але надсилаю їх через встановлене з’єднання SSL.
AaronLS

14
Щоб було зрозуміло: якщо ви не використовуєте HTTPS, не має значення, який JavaScript ви запускаєте на клієнті; MITM зможе змінити вміст вашої сторінки, перш ніж вона потрапить на клієнта. HTTPS - єдине рішення.
помічник

60

Перш за все, це НЕ покращує безпеку вашої програми (припустимо, що це веб-версія).

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

Чому до цього просто. TLS вирішує проблему (коли вона використовується із купленими сертифікатами, а не підписана самостійно), яка є досить великою в криптографії: Як я знаю, на якому сервері я розмовляю, це сервер, на який я думаю, з яким я говорю? Сертифікати TLS - це спосіб сказати: "Я, орган сертифікації, якому довіряє ваш браузер, засвідчує, що веб-сайт за адресою [url] має цей відкритий ключ із відповідним приватним ключем, який (приватний ключ) знає, виглядає лише сервер. Я підписав свій підпис у всьому документі, якщо хтось змінив його, ви можете бачити ".

Без TLS будь-яке шифрування стає безглуздим, тому що якщо я сиджу поруч з вами в кафе, я можу змусити ваш ноутбук / смартфон думати, що я сервер, а MiTM (Man in The Middle) - ви. У системі TLS ваш ноутбук / смартфон буде кричати "НЕЗАДАЧАЛЬНА З'ЄДНАННЯ", оскільки у мене немає сертифікату, який підписує орган, який відповідає вашому сайту. (Шифрування проти автентифікації).

Відмова від відповідальності: користувачі, як правило, клацають правою кнопкою через ці попередження: "Ненадійне з'єднання? Що? Я просто хочу, щоб мої фотографії кошенят! Додати виняток. Натисніть" Підтвердити. Натисніть " ТАК! Кошенята!"

Однак якщо ви дійсно не хочете купувати сертифікат, все-таки НЕ реалізовуйте хешування JavaScript на стороні клієнта (і використовуйте для цього бібліотеку standford (SJCL), НІКОЛИ НЕ ВПРОВАДЖАЙТЕ КРИПТО ВСЕ ВАС ).

Чому? Повторне використання пароля! Я можу вкрасти ваше cookie-сеанси (що дозволяє мені робити вигляд на вашому сервері, що я це ви) без HTTPS легко (див. Помилку). Однак якщо ви додасте на свою сторінку входу javascript, який, перш ніж надсилати, хеширує ваш пароль (використовуйте SHA256, а ще краще, використовуйте SHA256, надішліть їм створений відкритий ключ, а потім зашифруйте хешированний пароль, ви не можете використовувати сіль з цим), а потім надсилає хешований / зашифрований пароль на сервер. РЕАГУЙТЕ хеш на вашому сервері з сіллю та порівняйте його з тим, що зберігається у вашій базі даних (збережіть пароль так:

(SHA256(SHA256(password)+salt))

(збережіть сіль як простий текст у базі даних)). І надішліть свій пароль таким чином:

RSA_With_Public_Key(SHA256(password))

і перевірте свій пароль таким чином:

if SHA256(RSA_With_Private_Key(SHA256(sent_password))+salt_for_username) == stored_pass: login = ok

Тому що, якщо хтось нюхає вашого клієнта, він зможе увійти як ваш клієнт (викрадення сесії), але вони НІКОЛИ не побачать пароль прямого тексту (якщо тільки вони не змінять ваш JavaScript, однак, хакер зі зоряними повідомленнями, ймовірно, не буде знати, як / бути зацікавленим у цьому.) Отже, вони отримають доступ до вашого веб-сайту, але не до своєї електронної пошти / facebook / тощо. (для якого ваші користувачі, ймовірно, будуть використовувати той самий пароль). (Адреса електронної пошти буде або їхнім ім’ям для входу, або буде знайдено у їхньому профілі / налаштуваннях на вашому веб-сайті).


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

24

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

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

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


Редагувати серпня 2014 року: Google все сильніше наполягає на тому, щоб веб-сайти всюди переходили на HTTPS , адже забезпечення самої комунікації - це єдиний спосіб запобігти атакам нюхання мережі. Спроби затьмарити передані дані будуть лише перешкоджати, а не зупинятись, відданому зловмиснику, і можуть дати розробникам небезпечне помилкове відчуття безпеки.


Я вважаю, що ваша думка про те, що хешування клієнтів лише "трохи краща", справедлива, якщо ви орієнтовані виключно на отримання xпароля користувача та доступ до однієї послуги. Якщо врахувати колективний ефект, я б сказав, що це "набагато краще"; оскільки це перешкоджає створенню великих баз даних пошуку паролів, які використовуються для грубої соляної хеш-пам’яті в багатьох службах. ІМО. Для ознайомлення подивіться, що робить AWS Cognito у клієнті.
f1lt3r

17

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

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

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

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

До речі, подібне запитання, ймовірно, отримає більше відповідей експертів щодо безпеки StackExchange.


3
Повністю згоден з цим. Для клієнтського підходу до роботи потрібно було б також надіслати сіль клієнту, що призведе до недійсності всієї мети засолювання!
Джеймс Райт

@JamesWright: Справа в тому, щоб надсилати випадкову сіль для кожного використання, що запобігає незаконному повторному використанню повідомлень про вхід. (Форма атак повторення). Посилати ту саму сіль щоразу справді безглуздо.
MSalters

Що вам потрібно зробити, це використовувати "nonce" ( en.wikipedia.org/wiki/Cryptographic_nonce ). Таким чином, сервер також контролює сіль і робить це безпечним. Хешинг на стороні клієнта також важливий, щоб введений код JS не міг його легко знайти пізніше. Більше тут: stackoverflow.com/a/21716654/43615
Томас

Про використання солі + нонсе в процесі автентифікації входу дивіться цю відповідь: stackoverflow.com/a/24978909/43615
Thomas Tempelmann

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

5

Зауважте, що захист паролів від сторонніх сторін - це не все, що там є.

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

Тому хешування / шифрування на стороні клієнта має сенс.


Домовились! Дуже багато людей пропускають цей пункт. Якщо я завантажу вашу базу даних із засолених хешованих паролів, і я можу зламати лише один, використовуючи базу даних пошуку хешу, то, швидше за все, я можу зламати їх усіх. Після того, як у мене з'явилися 50k оригінальних паролів, тепер у мене є ключ до xкористувачів nсервісів, які шифруються лише на сервері. Якщо кожен сервіс однозначно хеширує пароль перед тим, як покинути клієнта, велика база даних паролів крос-сервісу стає набагато, значно меншою. Перевірте свій AWS трафік для входу, подивіться, що вони роблять. Ймовірно, мій дорогий Ватсон.
f1lt3r


1

Я нещодавно робив багато роботи над цим, IRL є два питання з хеш- симетричним шифруванням на стороні клієнта, що дійсно вбиває ідею: 1. Ви повинні повернути сіль на сервер ДЕЙШЕ ... та зашифрувати на стороні клієнта вам знадобиться пароль ... який перемагає мету. 2. Ви виставляєте свою хеш-реалізацію (не ВЕЛИЧЕЗНА угода, оскільки більшість сайтів використовують одну з 3 або 4 хеш-алго), що полегшує атаку (як тільки потрібно спробувати одну, а не n).

У кінцевому підсумку я перейшов до асиметричного шифрування клієнта за допомогою OpenPGP.js або подібного ... Це покладається на імпортований або створений на базі клієнта ключ клієнта та сервер, що надсилає його відкритим ключем. На сервер може бути відправлений лише відкритий ключ клієнта. Це захищає від MIM-атак і настільки ж безпечно, як і пристрій (на даний момент я зберігаю приватний ключ клієнта за замовчуванням у localStore, це демонстрація).

ОСНОВНА перевага цього в тому, що мені ніколи не потрібно зберігати дані користувачів / навіть у пам'яті незашифровані на моєму сервері / сховищі даних (а приватний ключ мого сервера фізично окремий)

Основою цього було надання людям способу безпечної комунікації там, де HTTPS обмежений (наприклад, Іран / Північна Корея) та просто цікавого експерименту.

Я FAR з перших, хто задумався над цим, http://www.mailvelope.com/ використовує це


1

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

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

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

Дані користувачів шифруються і на стороні браузера.

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

Деякі невеликі приклади обох цих методів є у моєму блозі http://glynrob.com/javascript/client-side-hashing-and-encryption/


1

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

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

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

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

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

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


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

0

Враховуйте це: -

Клієнт відправляє запит на сервер "У мене є пароль для підтвердження".

Сервер посилає клієнту одноразовий лише випадковий рядок. R $

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

Клієнт відправляє рядок на сервер, і якщо пароль ОК, сервер реєструється в системі.

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

Очевидно, всі інші (звичайні) заходи безпеки будуть вжиті.


0

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

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

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