@Galdar
Web, JS, PHP, NGINX, Linux

Как расшифровать JWT токен?

Вот есть пример на сайте
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Пытаюсь его расшифровать и не получиться.
$jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
$key = "";

$decoded = JWT::decode($jwt, $key, array('HS256'));
$answer = $decoded;

Я так понимаю дело в ключе. Но какой ключ писать то? Читаю про JWT но не могу понять

ДОП:
Как я понял ключ указан в футере
secret
5f51eb66b58a9150260974.png

И правильно я понимаю, что JWT токен который я получаю у него нужно взять хвос и перевести его. Только вот как и из чего пока не разобрался.
  • Вопрос задан
  • 11882 просмотра
Решения вопроса 2
Stalker_RED
@Stalker_RED
Токен состоит из трех частей разделенных точкой. Каждая часть кодируется немного модифицированным base64.
Первые две раскодируются вообще без ключа. В конце подпись, кодированная ключом. В вашем примере это
your-256-bit-secret (попробуйте там справа, где синенькое напечатать другой ключ и смотрите как меняется токен).

<?php
$key = 'your-256-bit-secret'; // ваш ключ
$jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
$jwtArr = array_combine(['header', 'payload', 'signature'], explode('.', $jwtToken));

var_export($jwtArr); /* -> разделяем по точкам
array (
  'header' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
  'payload' => 'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ',
  'signature' => 'SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
) */

echo PHP_EOL . base64_decode($jwtArr['header']) . PHP_EOL; // декодированный заголовок
// -> {"alg":"HS256","typ":"JWT"}
echo base64_decode($jwtArr['payload']) . PHP_EOL; // декодированная нагрузка
// -> {"sub":"1234567890","name":"John Doe","iat":1516239022}

$calculatedHash = hash_hmac( // сами считаем хеш
	'sha256',
	$jwtArr['header'] . '.' . $jwtArr['payload'],
	$key,
	true);

echo base64_encode($calculatedHash) . PHP_EOL;
// -> SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV/adQssw5c=

echo $jwtArr['signature'] . PHP_EOL;
// -> SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
// Похоже? Там слегка модифицированный base64


Третья часть - подпись. Если взять первые две части и получить sha265-хеш с использованием вашего ключа, то он должен совпасть с первой частью. Это подтвердит, что первые две части никто не изменял.

Хоть бы вики почитал, в самом деле :)
Ответ написан
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
JWT состоит из трёх частей, разделённых точками. Первая часть - заголовок, вторая - полезная нагрузка (payload), третья часть - подпись. Подпись представляет из себя шифрованный по ключу хэш от первых двух частей.

При выдаче токена сервер генерирует заголовок и полезную нагрузку, записывает их в JSON и кодирует в модифицированный BASE64. Получается две строки. Эти строки объединяются через точку и от полученной общей строки вычисляется подпись. Конкретный алгоритм вычисления указан в заголовке. Далее подпись через точку присоединяется к строке и получается полный токен.

При получении запроса с токеном сервер разделяет токен на части, распаковывает заголовок и находит алгоритм подписи. Затем он вычисляет контрольную подпись от первых двух частей токена и сравнивает её с полученной в токене. Если они совпадают, то токен признаётся правильным.

При использовании симметричного алгоритма один и тот же ключ знают как сервер, выдающий токен, так и сервер, проверяющий его. Асимметричное шифрование позволяет выдавать токен на одном сервере по закрытому ключу, а проверять на другом сервере по парному открытому ключу.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы