Понимание JWT от начала до конца
9 мая 2022 г.Безопасность и конфиденциальность данных пользователей вызывают все большую озабоченность в последние несколько лет. При этом JWT как одна из технологий борьбы с ним используется все чаще.
Безопасность и конфиденциальность данных пользователей вызывают все большую озабоченность в последние несколько лет. При этом JWT как одна из технологий борьбы с ним используется все чаще. Понимание JWT даст вам преимущество перед другими разработчиками программного обеспечения. JWT может показаться простым на первый взгляд, но его довольно сложно понять.
В этой статье мы рассмотрим в основном JWT и JWS. Кроме того, мы также быстро пройдем JWE, JWA и JWK. Цель этой статьи — помочь читателю понять концепцию JWT, не углубляясь в тему.
Кто они такие?
Итак, давайте посмотрим, что такое JWT, JWS, JWE, JWA и JWK.
Веб-токен JSON (JWT)
Во-первых, давайте посмотрим на определение JWT, данное в RFC 7519.
JSON Web Token (JWT) — это компактный формат представления утверждений,
предназначенный для сред с ограниченным пространством, таких как HTTP
заголовки авторизации и параметры запроса URI. JWT кодируют утверждения
для передачи в виде объекта JSON, который используется в качестве полезной нагрузки
структуры веб-подписи JSON (JWS) или в качестве
открытого текста структуры веб-шифрования JSON (JWE), что позволяет < br> утверждения должны быть подписаны цифровой подписью или защищены целостностью с помощью
кода аутентификации сообщения (MAC) и/или зашифрованы. JWT всегда
представлены с использованием компактной сериализации JWS или компактной
сериализации JWE.
Из текста мы можем понять, что JWT — это не структура, а набор утверждений в форме JWS или JWE в качестве способа самозащиты. В самой простой форме разница между JWS и JWE заключается в том, что каждый может видеть полезную нагрузку JWS, в то время как JWE зашифрована.
В этой статье мы больше узнаем о JWS, чем о JWE.
Веб-алгоритм JSON (JWA)
JWA (RFC 7518), что означает веб-алгоритм JSON, представляет собой спецификацию, определяющую алгоритм хеширования и шифрования для создания JWT.
Например, ниже приведены алгоритмы хеширования, которые мы можем использовать для создания JWT со структурой JWS.
Веб-ключ JSON (JWK)
JWK (RFC 7517) означает веб-ключ JSON. JWK — это структура данных JSON, которая содержит информацию о криптографическом ключе хэш-функции. Это способ сохранить ваш ключ хеширования в формате JSON.
```json
"кты": "ЕС",
"crv":"P-256",
"х": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
"у": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0",
"kid":"Открытый ключ, используемый в примере приложения A.3 спецификации JWS"
JWK обычно используется для размещения открытого ключа для хеш-функции с асимметричным ключом (закрытый ключ и открытый ключ), поэтому потребитель может получить ключ самостоятельно.
Веб-подпись JSON (JWS)
JWS (RFC 7515), что означает веб-подпись JSON, является одной из структур, используемых JWT. Это наиболее распространенная реализация JWT. JWS состоит из 3 частей: заголовка JOSE, полезной нагрузки и подписи.
Ниже приведен пример JWS в компактной сериализации.
```javascript
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV
Пример компактной сериализации JWS
Если мы декодируем JWS, мы получим заголовок JOSE (JavaScript Object Signing and Encryption):
```json
"алг": "HS256",
"тип": "JWT"
Полезная нагрузка:
```json
"суб": "1234567890",
"имя": "Джон Доу",
"иат": 1516239022
Следующая часть — подпись. Мы не будем его декодировать, потому что это значение в байтах.
```javascript
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Самый распространенный вопрос, связанный с JWT (в структуре JWS), заключается в том, что делает его безопасным, поскольку каждый может декодировать JWT и просматривать его данные. JWT безопасен, потому что его может создать не каждый, а только тот, у кого есть секретный ключ.
Веб-шифрование JSON (JWE)
JWE (RFC 7516), в отличие от JWS, шифрует свой контент с помощью алгоритма шифрования. Единственный, кто может видеть, что внутри JWT, это тот, у кого есть ключ.
Структура компактной сериализации JWE выглядит следующим образом:
```javascript
BASE64URL(UTF8(защищенный заголовок JWE)) || ’.’ ||
BASE64URL (зашифрованный ключ JWE) || ’.’ ||
BASE64URL (вектор инициализации JWE) || ’.’ ||
BASE64URL (шифрованный текст JWE) || ’.’ ||
BASE64URL (тег аутентификации JWE)
Давайте рассмотрим один пример:
```javascript
eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.RD09fEltrYPVNoGt2KY1Odv_5eDxkU4VX1f__P8b9zl9uzh5bmvvJy35dL-hYlUib1g63qnWBEfeSyDk5cAIQiMt6PZCBQzuWQJQlQtuo2UPLZznmLPqah37uHKB4a57q_lWf_W9soyZbO7Zj7QRNz4ZR4s5ozRHArSZcc1pAL-pYuHKyeh6Ey8t4bk66wkthjjfOjXvIfOlgbemhibegmE4GpQL6F-m0teqcAE-OxkaBRTmmb4AD5HdrCJWCIIuC52fzuWrhcoNmHM74ggtWUUjlHaKpwcVE-IWINTFaz5Pi9u4U3vnVNOZwDwB0TLSQvqnPwTZ-bYWNj8vH4TS_w.Pjo5QK1u1otxgcuBR7e8ew._OElhHugS2L6Kp04HhbFt6dLij_KXhO654RmT4JKyswYBX0wqRWt7ZzAE6eCHfJSJdMQYxqVSNloGb4OSIzYcTEo174lBZBINkHW-w2K6E0.QBDgBFizm80HLVkZvfBPCg
В примере используется алгоритм управления ключами RSA_OAEP_256 и AES_128_CBC_HMAC_SHA_256 в качестве алгоритма шифрования. Если мы расшифровали JWE, то получим:
```json
"исс": "https://codecurated.com",
"эксп": 1651417524,
"иат": 1651417224
Декодирование JWT
Теперь давайте более подробно рассмотрим JWT на следующем примере:
```javascript
eyjhbgcioijiuzi1niisimtpzci6ijiwmjitmdutmdeifq.eyjzdwiioiixmjmgnty3odkwiiwibmftzsi6ikjyawxp4grmlyzgf1cyisimlhdci6mty1myawxyw4grmlyzgf1-hrxmgxmlzgxmglzmlzgm.gmlizglizglzgm.ghehlizgmlzgm.ghehlizgmlzgm.ghehlizgmlizgmlizgmlizgmlizgmlizgmlizgmlizgmlizgm.clez-hrmlizglzgxmlizglzgxmlizglzgxmlizglzgxmlizglz
JWT в этом примере — это JWT с компактной структурой сериализации JWS. Нам нужно разделить JWT на .
(точка), и Base64 декодирует их, чтобы посмотреть, что внутри.
После разделения и декодирования JWT мы получим три части:
- Заголовок JOSE (подпись и шифрование объекта JavaScript)
- Полезная нагрузка
- Подпись
JOSE Заголовок
```javascript
eyJhbGciOiJIUzI1NiIsImtpZCI6IjIwMjItMDUtMDEifQ
После выполнения декодирования строки Base64 мы получим:
```json
"алг": "HS256",
"малыш": "01.05.2022"
Эта часть JWT называется заголовком JOSE. С помощью заголовка JOSE JWT может сообщить клиенту, как обращаться с JWT.
Давайте разберем два поля, которые есть в нашем JWT:
alg
: содержит информацию об алгоритме подписи JWT.
kid
: содержит информацию об идентификаторе ключа, используемого для проверки JWT. Подробнее об этом мы поговорим в разделе JWK.
alg
– это единственный обязательный заголовок, и он необходим в большинстве случаев, но существует множество других заголовков, которые вы можете проверить здесь.
Полезная нагрузка
Убрав заголовок JOSE, давайте взглянем на вторую часть, полезную нагрузку.
```javascript
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJyaWxpYW4gRmlyZGF1cyIsImlhdCI6MTY1MTQyMjM2NX0
После расшифровки:
```json
"суб": "1234567890",
"name": "Брилиан Фирдаус",
"иат": 1651422365
Эта часть JWT называется полезной нагрузкой. Есть поля с термином JWT-претензии (sub
, name
, iat
). Итак, сейчас самое время поговорить о претензиях JWT.
Существует три типа претензий JWT:
- Зарегистрированные претензии
- Публичные претензии
- Частные претензии
Давайте разберем его по порядку, начиная с зарегистрированных претензий. Зарегистрированные заявки — это заявки, которые изначально были задокументированы в RFC 7519.
iss
(Эмитент): указывает, кто является эмитентом JWT.
sub
(Subject): указывает идентификатор пользователя, запрашивающего JWT.
aud
(Аудитория): показывает, кто является предполагаемым потребителем JWT.
exp
(Expiration): время истечения срока действия JWT.
Вы можете просмотреть полный список здесь. Ни одно из этих утверждений не является обязательным, как указано в RFC 7519, но они необходимы для защиты вашего JWT.
Следующий тип претензий, который мы рассмотрим, — это частные претензии. Эти претензии могут быть какими угодно. Создатель или потребитель JWT должен определить имя и функцию утверждений.
:::Информация
При указании частных утверждений необходимо соблюдать осторожность, чтобы не вызвать коллизию имени.
Последним является общедоступное утверждение, которое является типом утверждения, которое публично регистрируется через IETF. Вы можете проверить список общедоступных претензий по адресу: https://www.iana.org/assignments/jwt/jwt.xhtml#claims.
У большинства людей нет никаких вариантов использования, требующих от них регистрации своих требований. Для лучшей практики вы можете выполнить поиск по списку публичных утверждений и использовать тот, который подходит для вашего случая использования.
Подпись
Если вы подошли к этой части, вам может быть интересно, что делает JWT безопасным, поскольку каждый может видеть его содержимое. Что ж, полезная нагрузка JWS предназначена для чтения всеми. Что делает JWT безопасным, так это то, что потребитель может проверить, кто выдал JWT.
Часть подписи в JWT создается с помощью хеш-функции. Если вы не знакомы с хэш-функцией, это алгоритм, который отображает объект в другой объект. Хеш-функция имеет две важные особенности, которые делают ее подходящей для защиты JWT:
- Работает только в одну сторону
- Результаты процесса хеширования всегда одинаковы
В этой статье мы рассмотрим две наиболее распространенные хэш-функции, используемые в JWT:
- HMAC SHA-256
- ECDSA256
Теперь давайте разберем подпись, которую мы используем в примере:
```javascript
qsg3HKPxM96PeeXl-sMrao00yOh1T0yQfZa-BsrtjHI
Который генерируется с использованием алгоритма MAC HS256 с секретным ключом (в base64) 7TgIAQCcYUA27bCI5+m7InRwp/mzQ+ArnFW/4c0Q51U=
.
Алгоритм MAC HS256 получает значение в байтах в качестве параметра секретного ключа и выдает значение в байтах на выходе. Таким образом, в отличие от заголовка и полезной нагрузки, мы получим значение в байтах, если попытаемся расшифровать подпись.
Давайте более подробно изучим алгоритм цифровой подписи или MAC.
HMAC SHA-256
Первый алгоритм, который мы рассмотрим, — это HMAC SHA-256 («HS256»), алгоритм MAC, использующий хеш-функцию с симметричным ключом. Хеш-функция с симметричным ключом означает только один ключ для хэш-функции. Таким образом, производитель и потребитель JWT будут использовать один и тот же ключ для подписи и проверки JWT. Преимущество использования этого алгоритма в том, что для создания хэша не требуется много ресурсов ЦП.
Минимальная длина байтов, рекомендуемая для секретного ключа HS256, составляет 32 байта. Секретный ключ должен быть сгенерирован с помощью криптографически защищенного генератора псевдослучайных чисел, чтобы обеспечить его случайность.
ECDSA-256
ECDSA-256 (ECDSA256
), в отличие от HMAC, представляет собой алгоритм, использующий функцию хеширования с асимметричным ключом. Хеш-функция с асимметричным ключом означает, что нам нужно сгенерировать два ключа. Один ключ называется закрытым ключом, который можно использовать как для подписи, так и для проверки подписи JWT. Другой ключ называется открытым ключом, который можно использовать только для проверки подписи JWT.
Как следует из их названия, открытый ключ может храниться в общедоступном пространстве (обычно в виде JWK), поэтому клиент, которому необходимо проверить вашу подпись JWT, может быстро его получить. Напротив, закрытый ключ должен быть защищен и рассматриваться как учетные данные.
Какую функцию хеширования выбрать?
Мы изучили два алгоритма, HS256 и ECDSA256, но когда выбрать один вместо другого? Вы можете легко принять решение об этом, подумав, не являются ли производитель и потребитель JWT одними и теми же компонентами.
Если потребителем JWT является тот же компонент, вы можете использовать алгоритм HS256. Наиболее распространенный вариант использования этой хэш-функции — создание системы аутентификации с использованием JWT.
:::Информация
Некоторые люди считают HS256 своего рода анти-шаблоном, потому что JWT предположительно используется для повышения безопасности, но в большинстве случаев использования этого алгоритма безопасность снижается.
Например, предположим, что вы планируете использовать JWT в качестве сеанса проверки подлинности вместо базы данных. В этом случае ваша система более небезопасна, потому что вы не можете истечь срок действия JWT, поэтому вы не можете удалить сеансы.
С другой стороны, если JWT создается и потребляется другим компонентом, вы можете использовать ECDSA256. Таким образом, вы можете защитить свой ключ и гарантировать, что никто другой (даже владелец открытого ключа) не сможет создать JWT от вашего имени.
Хранение открытого ключа в виде JWK (набор веб-ключей JSON)
Если вы планируете позволить публике использовать и проверять ваш JWT, рекомендуется разместить открытый ключ как JWK на URL-адресе. Таким образом, если потребитель хочет проверить ваш JWT, он может запросить определенный URL-адрес, на котором размещены JWK, и получить открытый ключ.
```json
"ключи": [
«кты»: «ЕС»,
"малыш": "01.05.2022",
"x": "g_pYyqY7Htj8Aa989Ura0_mwRdqJPEnhknKzaUrztj8",
"y": "MwOFYLE-VYre92hU0iDjNx36dk7cX6xdGgdgLIPt6Ts",
"crv": "П-256"
«кты»: «ЕС»,
"малыш": "01.01.2020",
"x": "6bw04ZlSMjxVzC7gXv75XAposOVTONh45ZPR0AeYaoU",
"y": "vYyCSIt0m5k4Q5A_uW8h3nEYJvgA8PgREERLcaiAHgQ",
"crv": "П-256"
Возможно, вы заметили несколько ключей в JSON, поэтому он называется JSON Web Key Set. Если в вашем продукте используется более одного ключа, вы можете разместить каждый ключ в JWK. Чтобы определить, какой ключ использовать, вам нужно будет добавить поле «ребенок» или идентификатор ключа в заголовок JOSE.
```json
"алг":"ES256",
"малыш": "2022-05-01"
Таким образом, клиент будет знать, какой ключ нужно получить, сравнивая «ребенок» в заголовке JOSE JWT с ключом в JWK. Остальные поля вместе образуют открытый ключ.
Забрать
В этой статье мы узнали, что:
- JWT — это абстрактная концепция, позволяющая одной или нескольким сторонам безопасно обмениваться информацией. Реализация JWT представлена в виде JWS или JWE.
- Функция различия между JWS и JWE заключается в том, что JWS позволяет всем видеть свою полезную нагрузку, в то время как JWE не позволяет это делать с помощью метода шифрования.
- Что делает JWS безопасным, несмотря на то, что каждый может видеть его полезную нагрузку, так это то, что создатель JWS может быть проверен по его подписи с использованием MAC или алгоритма проверки подписи. Таким образом, потребитель может быть уверен, что тот, кто создал JWT, является тем, для кого он предназначен.
- Мы изучили два типа алгоритмов: HS256 и ECDSA256. HS256 подходит, когда производитель и потребитель JWT являются одними и теми же компонентами, а ECDSA256 подходит, когда производитель и потребитель являются разными компонентами.
- Мы можем использовать JSON Web Key Set для размещения открытого ключа для функции хеширования с асимметричным ключом. Вам нужно установить поле kid в заголовке JOSE вашего JWT, чтобы потребитель мог сравнить его с полем в JWK, чтобы получить совместимый ключ.
Увы, хочу поблагодарить вас за то, что дочитали до конца. Следующий шаг, который вы можете предпринять, — научиться его реализовывать. Существует множество библиотек для популярных языков программирования, которые вы можете проверить здесь.
Также опубликовано здесь
Оригинал