Если вы можете декодировать JWT, как они защищены?

Если я получу JWT и смогу декодировать полезную нагрузку, насколько это безопасно? Разве я не могу просто извлечь токен из заголовка, декодировать и изменить информацию о пользователе в полезной нагрузке и отправить ее обратно с тем же правильным закодированным секретом?

Я знаю, что они должны быть в безопасности, но мне бы очень хотелось понять технологии. Чего мне не хватает?

Ответ 1

JWT могут быть подписаны, зашифрованы или оба. Если токен подписан, но не зашифрован, каждый может прочитать содержимое токена, но если вы не знаете секретный ключ, вы не сможете его изменить. В противном случае получатель заметит, что подпись больше не будет совпадать.

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

Предположим, Алиса хочет отправить JWT Бобу. Они оба знают какой-то общий секрет. Мэллори не знает этого секрета, но хочет вмешаться и изменить JWT. Чтобы предотвратить это, Алиса вычисляет Hash(payload + secret) и добавляет это как подпись.

При получении сообщения Боб также может рассчитать Hash(payload + secret), чтобы проверить, совпадает ли подпись. Однако, если Мэллори что-то изменит в контенте, она не сможет рассчитать подходящую подпись (это будет Hash(newContent + secret)). Она не знает секрета и не может его узнать. Это означает, что если она что-то изменит, подпись больше не будет совпадать, и Боб просто не примет JWT больше.

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

Ответ 2

Вы можете перейти на jwt.io, вставить свой токен и прочитать содержимое. Это изредка для многих людей изначально.

Короткий ответ заключается в том, что JWT не относится к шифрованию. Он заботится о валидации. То есть, он всегда может получить ответ для "Использовать содержимое этого токена"? Это означает, что манипулирование пользователем токена JWT бесполезно, потому что сервер будет знать и игнорировать токен. Сервер добавляет подпись на основе полезной нагрузки при выдаче токена клиенту. Позже он проверяет полезную нагрузку и соответствующую подпись.

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

  • Простейшая причина заключается в том, что она предполагает, что это большая проблема. Например, если вы работаете с клиентом, например с веб-браузером, вы можете хранить токены JWT в файле cookie secure + httpsOnly (не может быть прочитан Javascript +, не может быть прочитан HTTP) и разговаривает с сервером через зашифрованный канал (HTTPS). Как только вы узнаете, что у вас есть безопасный канал между сервером и клиентом, вы можете безопасно обменивать JWT или что-то еще, что вам нужно.

  • Это просто. Простая реализация упрощает принятие, но также позволяет каждому слою делать то, что он делает лучше всего (пусть HTTPS обрабатывает шифрование).

  • JWT не предназначен для хранения конфиденциальных данных. Когда сервер получает токен JWT и проверяет его, он может свободно искать идентификатор пользователя в своей собственной базе данных для получения дополнительной информации для этого пользователя (например, разрешения, почтовый адрес и т.д.). Это уменьшает размер JWT и предотвращает непреднамеренную утечку информации, потому что все знают, что не хранить конфиденциальные данные в JWT.

Это не слишком отличается от того, как работают файлы cookie. Файлы cookie часто содержат незашифрованные данные. Если вы используете HTTPS, тогда все будет хорошо. Если вы этого не сделаете, целесообразно зашифровать сами файлы cookie. Не делать этого будет означать, что возможна атака "человек в середине" - прокси-сервер или интернет-провайдер читает файлы cookie, а затем повторяет их позже, притворяясь вами. По аналогичным причинам JWT всегда следует обменивать на безопасном уровне, таком как HTTPS.

Ответ 3

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

Важно понимать различие между эмитентом и верификатором. Получатель токена отвечает за его проверку.

Существует два важных шага в безопасном использовании JWT в веб-приложении: 1) отправлять их по зашифрованному каналу и 2) проверять подпись сразу после ее получения. Асимметричный характер криптографии с открытым ключом делает проверку подписи JWT возможной. Открытый ключ проверяет, что JWT был подписан его соответствующим личным ключом. Никакая другая комбинация клавиш не может выполнять эту проверку, тем самым предотвращая попытки олицетворения. Следуйте этим двум шагам, и мы с математической гарантией можем гарантировать подлинность JWT.

Дополнительная информация: Как открытый ключ проверяет подпись?

Ответ 4

Только JWT privateKey, который находится на вашем сервере, расшифрует зашифрованный JWT. Те, кто знает privateKey, смогут расшифровать зашифрованный JWT.

Скройте privateKey в безопасном месте на вашем сервере и никогда не рассказывайте кому-либо privateKey.

Ответ 5

Я бы посоветовал взглянуть на 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

Ответ 6

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

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