2014-12-04 1 views
118

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

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

ответ

169

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

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

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

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

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

+1

Значит, подпись изменяется при изменении полезной нагрузки? Я был под впечатлением, что токен был в формате [header]. [Полезная нагрузка]. [Подпись] - это подпись, рассчитанная по комбинации полезной нагрузки и секретности? Если бы это было так, разве полезная нагрузка с другим идентификатором была бы одинаковой для этого секрета? Например, если данные были {id: 1}, и это используется для вычисления сигнатурной части токена с секретом, не означает ли это, что {id: 2} будет действительным для пользователя 2, и поэтому пользователь 1 может изменить id до 2, а токен будет одинаковым? – PixMach

+0

Например, я перехожу сюда и изменяю данные в полезной нагрузке, и он говорит, что подпись действительна, если я не ввел недопустимые символы: http://jwt.io/ http://grab.by/CNGS – PixMach

+0

@PixMach Отредактировано Ответ – Misch

45

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

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

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

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

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

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

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

5

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

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

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

Больше чтение: How does a public key verify a signature?

1

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

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

+1

они могут читать, но не могут измениться! – phpdroid

0

Данные внутри JWT подписаны и зашифрованы, это не значит, что они безопасны. JWT не предоставляет гарантию на конфиденциальные данные.

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

Насколько я знаю, JWT не обеспечивает безопасность.

Thanks

Смежные вопросы