Як надійно надіслати пароль через HTTP?


115

Якщо на екрані входу користувач подає форму із своїм ім'ям користувача та паролем, пароль надсилається простим текстом (навіть із POST, виправте мене, якщо я помиляюся).

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

Мені відомо, що HTTPS - це вирішення проблеми, але чи є спосіб забезпечити хоча б якийсь рівень безпеки за допомогою стандартного протоколу HTTP (POST-запит)? (можливо, якось використовують javascript)

EDIT Я, можливо, залишив деякі важливі речі.

Те, про що я хотів, - це сторінка - це сторінка входу, створена PHP, яка, звичайно, надсилається користувачеві в HTTP GET-запиті як HTML-файл. Між сервером та клієнтом не встановлено (@Jeremy Powel) зв'язку, тому я не можу створити такий протокол рукостискання. І я хочу, щоб весь процес був прозорим для користувача - він хоче подати пароль, а не мати справу з криптографією.

Дякую.


1
Напевно, ви не зможете цього досягти без того, щоб клієнт використовував криптографію, але користувачеві не доведеться бачити такий процес. Він просто вводить свій пароль і код, який створює ваш PHP (наприклад, javascript), обробляє все це за вас.
Джеремі Пауелл

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

1
Отже, S у вашій пропозиції може бути лише паролем (або ім'ям користувача + паролем, поєднаним будь-яким чином), оскільки це єдиний "секрет", який має користувач. Я прав? Таким чином, рішення було б таким, як наступне: - Сервер надає HTML-сторінці приховане поле форми R - Користувач вводить пароль, і перед тим, як пароль буде відправлений, javascript обчислює H (R, S) і відправляє його на сервер, можливо, навіть використовуючи AJAX - Сервер обчислює H (R, S) і порівнює його з отриманим і надсилає відповідь на запит ajax, чи пройшла автентифікація - javascript перенаправляє браузер на потрібну веб-сторінку
Kornelije Petak

2
@jeremy powell - хоча те, що ви описуєте, є звичайною практикою, воно також є вразливим для посередника, який може нюхати файли cookie із заголовка та видавати себе за користувача, використовуючи печиво. Людей посередніх атак важко захистити, якщо ви не використовуєте HTTPS
jnoss

1
Для того, хто в майбутньому стане цим питанням: ПІСЛЯ входу в систему, вам також потрібно забезпечити cookie сеансу. (Отже: використовувати HTTPS насправді набагато простіше.)
Ар'ян

Відповіді:


66

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


14
... і "Але я повинен платити за сертифікат SSL !!" не є дійсною скаргою, оскільки ви можете отримати їх за 30 доларів у ці дні. Чи справді ваші дані не коштують 30 баксів для захисту?
caf

3
Що робити, якщо веб-хостинг, на який ви підписалися, не підтримує додавання сертифікатів SSL?
Кальмарій

89
@Calmarius - тоді ви переходите до справжнього веб-хостингу
BornToCode

3
@BornToCode Це технічно означає, що вам потрібно мати спеціальний IP-адресу і вам потрібно володіти серверним обладнанням (або принаймні VPS), щоб використовувати HTTPS. Спільні веб-хости не можуть робити HTTPS, якщо весь сервер не захищений сертифікатом власника хоста.
Кальмарій

6
спільні веб-хости, безумовно, можуть робити https, використовуючи en.wikipedia.org/wiki/Server_Name_Indication
Брайан Мінтон

39

Безпечна автентифікація - широка тема. У двох словах, як зазначав @ jeremy-powell, завжди надайте перевагу надсиланню облікових даних через HTTPS замість HTTP. Це забере багато головних болів, пов'язаних із безпекою.

Сертифікати TSL / SSL в наші дні досить дешеві. Насправді, якщо ви зовсім не хочете витрачати гроші, є безкоштовний letsencrypt.org - автоматизований орган сертифікації.

Ви можете піти ще на крок і скористатися caddyserver.com який викликає letsencrypt у фоновому режимі.

Тепер, як тільки ми вивели HTTPS з шляху ...

Ви не повинні надсилати логін та пароль через корисні навантаження POST або параметри GET. Використовуйте натомість Заголовок авторизації (Базова схема автентифікації доступу), який будується наступним чином:

  • Ім'я користувача та пароль поєднуються в рядок, розділений двокрапкою, наприклад: ім'я користувача: пароль
  • Отримана рядок кодується за допомогою варіанту RFC2045-MIME Base64, за винятком обмежень 76 char / line.
  • Спосіб авторизації та пробіл, тобто "Basic", потім ставлять перед кодованим рядком.

джерело: Вікіпедія: Заголовок авторизації

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

Є декілька вагомих причин, щоб використовувати заголовок авторизації

  1. Це стандарт
  2. Це просто (після того, як ви навчитеся ними користуватися)
  3. Це дозволить вам увійти на рівні URL-адреси, як-от так: https://user:password@your.domain.com/login(наприклад, Chrome автоматично перетворить його в Authorizationзаголовок)

ВАЖЛИВО:
Як вказував @zaph у своєму коментарі нижче, надсилання конфіденційної інформації як GET-запит не є гарною ідеєю, оскільки це, швидше за все, опиниться в журналах сервера.

введіть тут опис зображення


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

Ааа ... зовсім не. Знімок екрана, який ви бачите, модифікується для того, щоб проілюструвати те, що відбувається в браузері. Щойно ви натиснете кнопку "Ввести", браузер перетворить ваш URL, створивши Authorizationзаголовок. Просто дайте йому піти. Колоди нагадують чисті. І звичайно, якщо ви телефонуєте з сервера (якщо це такий сценарій, який ви переживаєте), ви, звичайно, повинні генерувати заголовок програмно.
FullStackForger

Ви не можете ввійти в систему, що не можете бачити. username:password@urlз браузера перекладається на: url+ Authorizationзаголовок запиту. Щодо запитів GET ... добре, як я вже сказав, використовуйте заголовок Authroziation. Так краще.
FullStackForger

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

3
Слід підкреслити, що це рішення працює лише в тому випадку, якщо ви вже шифруєте з'єднання з TLS / SSL. base64 - не шифрування.
Скотт

14

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

  1. Сервер відправляє клієнту випадкове число, R.
  2. Клієнт відправляє H (R, S) назад на сервер (де H - криптографічна хеш-функція, як SHA-256)
  3. Сервер обчислює H (R, S) і порівнює його з відповіддю клієнта. Якщо вони відповідають, сервер знає, що клієнт знає пароль.

Редагувати:

Тут виникає проблема зі свіжістю R та тим, що HTTP без громадянства. Це можна вирішити, якщо сервер створив секрет, назвемо його Q, що знає лише сервер . Тоді протокол виходить так:

  1. Сервер генерує випадкове число R. Потім він відправляє клієнту H (R, Q) (який клієнт не може бути підроблений).
  2. Клієнт відправляє R, H (R, Q) і обчислює H (R, S) і відправляє все це назад на сервер (де H - криптографічна хеш-функція, як SHA-256)
  3. Сервер обчислює H (R, S) і порівнює його з відповіддю клієнта. Потім потрібно R і обчислює (знову) H (R, Q). Якщо версії H (R, Q) і H (R, S) клієнта відповідають перерахунку сервера, сервер вважає, що клієнт має автентифікацію.

Зауважимо, оскільки H (R, Q) не може бути підроблений клієнтом, H (R, Q) виконує функції cookie (і тому може бути реалізований фактично як cookie).

Ще одна редакція:

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


+1 - вам потрібно буде обчислити відповідь на стороні клієнта за допомогою javascript (або Flash / Silverlight / тощо)
orip

10
Не зупиняє людину посеред або нападу на себе. Наприклад, через wifi. Схоже, це просто дасть помилкове відчуття безпеки, IMO.
Том Хоутін - тайклін

2
Це захищає від пасивних атак, але людина в середині все ж може напасти.
Дуглас Лідер

7
Також він вимагає від сервера знати оригінальний пароль.
Дуглас Лідер

3
Не винаходити криптовалюту! (у виробництві)
Брайанф

11

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

Інакше, якщо ви хочете щось зробити через HTTP. Я б робив щось подібне.

  1. Сервер вбудовує свій відкритий ключ на сторінку входу.
  2. Клієнт заповнює форму для входу та натискає кнопку.
  3. Запит AJAX отримує поточну позначку часу від сервера.
  4. Сценарій клієнтської сторони об'єднує облікові дані, часову позначку та сіль (хеширується з аналогових даних, наприклад, рухи миші, події натискання клавіш), шифрує її за допомогою відкритого ключа.
  5. Подає отриманий хеш.
  6. Сервер розшифровує хеш
  7. Перевіряє, чи часова мітка досить недавня (дозволяє лише коротке вікно 5-10 секунд). Відхиляє вхід, якщо позначка часу занадто стара.
  8. Зберігає хеш 20 секунд. Відхиляє той самий хеш для входу протягом цього інтервалу.
  9. Аутентифікує користувача.

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

Про безпеку маркера сеансу. Це трохи складніше. Але можливо повторно використовувати маркер вкраденого сеансу трохи складніше.

  1. Сервер встановлює додатковий cookie сеансу, який містить випадкову рядок.
  2. Веб-переглядач повертає цей cookie на наступний запит.
  3. Сервер перевіряє значення файлу cookie, якщо воно інше, воно знищує сеанс, інакше все в порядку.
  4. Сервер знову встановлює файл cookie з різним текстом.

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

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

Про реалізацію: RSA, мабуть, є найбільш відомим алгоритмом, але для довгих клавіш він досить повільний. Я не знаю, якою швидкою була б реалізація PHP або Javascript. Але, ймовірно, є більш швидкі алгоритми.


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

@michaellindahl асиметричне шифрування означає, що для розшифрування речей можна використовувати лише приватний ключ - який ніколи не залишає сервер. Відкриті ключі можна використовувати лише для шифрування.
Комора Ден

2
Комп'ютер між браузером та сервером може змінити відкритий ключ на сторінці входу.
Антті

Дякуємо, що поділилися вашими методами, я знайшов дуже цікаве все. Часова позначка, що додається при надсиланні вірогідних даних, є гарним уловом! Одне запитання щодо використання додаткового файлу cookie сеансу, значення якого - випадковий рядок: це як маркер лише для наступного запиту?
Віктор

4

Я б використовував систему обміну ключами Diffie-Hellman на стороні сервера та клієнта з AJAX або декількома формами подання (я рекомендую попередню), хоча я не бачу в Інтернеті жодної хорошої реалізації. Пам’ятайте, що бібліотека JS завжди може бути пошкоджена або змінена MITM. Локальне сховище може використовуватися для боротьби з цим, певною мірою.


4

Ви можете використовувати SRP для використання захищених паролів через незахищений канал. Перевага полягає в тому, що навіть якщо зловмисник нюхає трафік або компрометує сервер, вони не можуть використовувати паролі на іншому сервері. https://github.com/alax/jsrp - бібліотека javascript, яка підтримує захищені паролі через HTTP у веб-переглядачі або на сервері (через вузол).


1

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

Ось вихідний код Java, який використовує асиметричний шифр RSA (використовується PGP) для зв'язку: http://www.hushmail.com/services/downloads/


0

ви можете використовувати ssl для свого хоста, є безкоштовний проект для ssl, як letsencrypt https://letsencrypt.org/


2
Перевірте третє речення, про яке йдеться. (Також завжди читайте інші відповіді, щоб переконатися, що ви не додаєте менш деталізований дублікат.)
Nathan Tuggy

0

Використання https звучить тут найкращим варіантом (сертифікати зараз не такі дорогі). Однак якщо http - вимога, ви можете скористатися якоюсь підпискою - записати її на стороні сервера та розшифрувати в браузері користувачів (ключ надсилання окремо).

Ми використовували це під час реалізації safevia.net - реєстрація проводиться на сторонах клієнтів (відправника / одержувача), тому дані користувачів не доступні на мережевому та серверному рівні.

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