Якщо ви можете розшифрувати JWT, як вони захищені?


302

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

Я знаю, що вони повинні бути захищеними, але я просто хотів би дуже зрозуміти технології. Що я пропускаю?


2
md5('original messaged' + secret) != md5('changed message' + secret)таким чином, якщо хтось змінить повідомлення, ви можете його виявити
Pithikos

правда для ідеального випадку, проте, md5 має зіткнення. @Pithikos
Яш Кумар Верма

@YashKumarVerma так, це просто продемонструвати суть цього, оскільки всі знають md5.
Пітікос

1
@ user1955934 це base64 закодовано, а не зашифровано. Ви можете просто розшифрувати його будь-яким декодером base64.
Пітікос

1
тож клієнту потрібно буде надіслати як хеш, так і jwt маркер? а пізніше на стороні сервера вони спробують хеш-код jwt, використовуючи секрет, і порівняти з хешем?
користувач1955934

Відповіді:


387

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

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

Припустимо, Аліса хоче відправити JWT до Боба. Вони обоє знають якусь спільну таємницю. Меллорі не знає цієї таємниці, але хоче втрутитися і змінити JWT. Щоб запобігти цьому, Аліса розраховуєHash(payload + secret) та додає це як підпис.

Отримавши повідомлення, Боб також може розрахувати, Hash(payload + secret)щоб перевірити, чи відповідає підпис. Якщо, проте, Меллорі щось змінює у вмісті, вона не зможе обчислити відповідний підпис (що було б Hash(newContent + secret)). Вона не знає секрету і не має можливості дізнатися її. Це означає, що якщо вона щось змінить, підпис більше не збігатиметься, і Боб просто більше не прийме JWT.

Припустимо, я надсилаю іншу людину повідомлення {"id":1}та підписую його Hash(content + secret). (+ тут ​​просто конкатенація). Я використовую функцію SHA256 Hash, а підпис я отримую: 330e7b0775561c6e95797d4dd306a150046e239986f0a1373230fda0235bda8c. Тепер ваша черга: зіграйте роль Меллорі та спробуйте підписати повідомлення {"id":2}. Ти не можеш, бо не знаєш, яким секретом я користувався. Якщо я вважаю, що одержувач знає секрет, він МОЖЕ обчислити підпис будь-якого повідомлення і перевірити, чи правильно він.


8
Отже, підпис змінюється при зміні корисного навантаження? У мене було враження, що маркер у форматі [заголовок]. [Корисний вантаж]. [Підпис] підпис обчислюється комбінацією корисного навантаження та секрету? Якби це було так, невже корисна навантаження з іншим ідентичним номером не буде однаковою для цієї таємниці? Як би, якщо дані були {id: 1}, і це використовується для обчислення частини підпису маркера з секретом, чи це не означає, що {id: 2} буде дійсним для користувача 2, і тому користувач 1 міг би змінитися id до 2 і маркер був би таким же?
PixMach

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

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

30
У мене пов'язане питання. Що заважає комусь видавати себе за Алісу за скопійованим JWT?
Безморозний

25
Якщо хтось має JWT, він може представити себе Алісою. Тож вам слід бути обережними, як ви зберігаєте та надсилаєте їх. Ви також повинні встановити термін його дії в корисному навантаженні. Таким чином, якщо хтось викраде JWT, у них є обмежений термін для його використання. Подивіться на stormpath.com/blog/…
Geraint Anderson

134

Ви можете перейти jwt.io, вставити маркер і прочитати вміст. Спочатку це дуже цікаво для багатьох.

Коротка відповідь полягає в тому, що JWT не стосується себе шифрування. Це дбає про перевірку. Тобто, завжди можна отримати відповідь "Чи маніпулювати вмістом цього маркера"? Це означає, що маніпуляція з токеном JWT користувачем є марною, оскільки сервер буде знати і зневажати маркер. Сервер додає підпис на основі корисного навантаження при видачі маркера клієнту. Пізніше він перевіряє корисне навантаження та відповідність підпису.

Логічне питання полягає в тому, яка мотивація не стосуватися себе зашифрованого вмісту?

  1. Найпростіша причина полягає в тому, що вона припускає, що це вирішена проблема здебільшого. Наприклад, якщо ви маєте справу з таким клієнтом, як веб-браузер, ви можете зберігати маркери JWT у файлі cookie secure(не передається через HTTP, лише через HTTPS) таhttpOnly (не може читатись через Javascript) і спілкується з сервером над зашифрований канал (HTTPS). Коли ви дізнаєтесь, що у вас є захищений канал між сервером і клієнтом, ви можете надійно обміняти JWT або все, що завгодно.

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

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

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


4
Зверніть увагу! JWT завжди слід обміняти на захищений шар, як HTTPS
codemirror

Але якщо JWT захищений лише через HTTPS, то чому б просто не надіслати корисний вантаж? POST -> ім'я користувача, пароль. Це все ще зашифровано правильно?
GeekPeek

@GeekPeek для цього вам слід прочитати основи JWT, але сеанс Auth, як ви згадуєте, часто все, що вам потрібно. JWT пропонує деякі інші переваги, але робить деякі компроміси webskeleton.com/webdev/2019/10/22/…
aleemb

17

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

Важливо розуміти відмінність між емітентом і верифікатором. Одержувач жетона несе відповідальність за його перевірку.

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

Більше читання: Як відкритий ключ перевіряє підпис?


2

Давайте відмовимося від самого початку:

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

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

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

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

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

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

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

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

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

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

Таким чином, веб-маркер Json виглядає як ліва частина цього скріншота, яка була знята з відладчика JWT на jwt.ioSo, по суті, це рядок кодування, що складається з трьох частин. Заголовок, корисне навантаження та підпис Тепер заголовок - це лише деякі метадані про сам маркер, а корисне навантаження - це дані, які ми можемо кодувати в маркер, будь-які дані, які нам дійсно потрібні. Отже, чим більше даних ми хочемо кодувати тут, тим більший JWT. У будь-якому разі, ці дві частини - це просто звичайний текст, який буде закодований, але не зашифрований.

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

І весь цей процес тоді називається підписанням веб-маркера Json . Алгоритм підписання займає заголовок, корисне навантаження та секрет для створення унікальної підпису. Тож тільки ці дані плюс секрет можуть створити цей підпис, все правильно? Потім разом із заголовком та корисним навантаженням цей підпис формує JWT, який потім надсилається клієнту. введіть тут опис зображення

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

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

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

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


1

Лише privateWey JWT, який знаходиться на вашому сервері, розшифрує зашифрований JWT. Ті, хто знає privateKey, зможуть розшифрувати зашифрований JWT.

Приховуйте privateKey у захищеному місці на вашому сервері і ніколи не повідомляйте нікому про privateKey.


1
JWT не завжди шифруються. Вони можуть бути підписані, зашифровані, підписані потім зашифровані, або зашифровані, потім підписані.
csauve

0

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

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


-1

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

Довідкова посилання: https://www.npmjs.com/package/node-webtokens

jwt.generate('PBES2-HS512+A256KW', 'A256GCM', payload, pwd, (error, token) => {
  jwt.parse(token).verify(pwd, (error, parsedToken) => {
    // other statements
  });
});

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

Простий приклад, який я створив: https://github.com/hansiemithun/jwe-example

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