Если я получу JWT и смогу декодировать полезную нагрузку, насколько это безопасно? Разве я не могу просто извлечь токен из заголовка, декодировать и изменить информацию о пользователе в полезной нагрузке и отправить ее обратно с тем же правильным закодированным секретом?
Я знаю, что они должны быть в безопасности, но мне бы очень хотелось понять технологии. Чего мне не хватает?
security
jwt
express-jwt
PixMach
источник
источник
md5('original messaged' + secret) != md5('changed message' + secret)
таким образом, если кто-то изменяет сообщение, вы можете обнаружить егоОтветы:
JWT могут быть подписаны, зашифрованы или оба. Если токен подписан, но не зашифрован, каждый может прочитать его содержимое, но если вы не знаете секретный ключ, вы не сможете его изменить. В противном случае получатель заметит, что подпись больше не будет совпадать.
Ответ на ваш комментарий: Я не уверен, правильно ли я понимаю ваш комментарий. Просто чтобы быть уверенным: вы знаете и понимаете цифровые подписи? Я просто кратко объясню один вариант (HMAC, который является симметричным, но есть много других).
Давайте предположим, что Алиса хочет отправить JWT Бобу. Они оба знают какой-то общий секрет. Мэллори не знает этого секрета, но хочет вмешаться и изменить JWT. Чтобы предотвратить это, Алиса вычисляет
Hash(payload + secret)
и добавляет это как подпись.При получении сообщения Боб также может вычислить
Hash(payload + secret)
, совпадает ли подпись. Однако, если Мэллори что-то изменит в контенте, она не сможет рассчитать соответствующую подпись (что было быHash(newContent + secret)
). Она не знает секрета и не может его узнать. Это означает, что если она что-то изменит, подпись больше не будет совпадать, и Боб просто не примет JWT больше.Предположим, я отправил другому человеку сообщение
{"id":1}
и подписал егоHash(content + secret)
. (+ это просто конкатенация здесь). Я использую функцию SHA256 Hash, а подпись я получаю:330e7b0775561c6e95797d4dd306a150046e239986f0a1373230fda0235bda8c
. Теперь ваша очередь: сыграйте роль Мэллори и попытайтесь подписать сообщение{"id":2}
. Вы не можете, потому что вы не знаете, какой секрет я использовал. Если я полагаю, что получатель знает секрет, он МОЖЕТ вычислить подпись любого сообщения и проверить его правильность.источник
Вы можете перейти
jwt.io
, вставить свой токен и прочитать содержимое. Поначалу это раздражает многих людей.Короткий ответ: JWT не занимается шифрованием. Это заботится о проверке. То есть он всегда может получить ответ на вопрос «Управлялось ли содержимым этого токена»? Это означает, что пользовательские манипуляции с токеном JWT бесполезны, поскольку сервер будет знать и игнорировать токен. Сервер добавляет подпись на основе полезной нагрузки при выдаче токена клиенту. Позже он проверяет полезную нагрузку и соответствующую подпись.
Логичный вопрос: что является мотивацией для того, чтобы не интересоваться зашифрованным содержимым?
Самая простая причина заключается в том, что предполагается, что это по большей части решенная проблема. Если вы работаете с таким клиентом, как веб-браузер, например, вы можете сохранить токены JWT в файле cookie, который
secure
(не передается по HTTP, только через HTTPS) иhttpOnly
(не может быть прочитан Javascript), и общается с сервером через зашифрованный канал (HTTPS). Как только вы узнаете, что у вас есть безопасный канал между сервером и клиентом, вы можете безопасно обмениваться JWT или чем-то еще, что вам нужно.Это делает вещь простой. Простая реализация облегчает принятие, но также позволяет каждому уровню делать то, что у него получается лучше всего (пусть HTTPS обрабатывает шифрование).
JWT не предназначен для хранения конфиденциальных данных. Как только сервер получает токен JWT и проверяет его, он может свободно искать идентификатор пользователя в своей собственной базе данных для получения дополнительной информации для этого пользователя (например, разрешения, почтовый адрес и т. Д.). Это делает JWT небольшим по размеру и предотвращает непреднамеренную утечку информации, потому что каждый знает, как не хранить конфиденциальные данные в JWT.
Это не слишком отличается от того, как сами куки работают. Файлы cookie часто содержат незашифрованные данные. Если вы используете HTTPS, то все хорошо. Если нет, то желательно зашифровать конфиденциальные файлы cookie. Невыполнение этого условия будет означать, что атака «человек посередине» возможна - прокси-сервер или Интернет-провайдер читает файлы cookie, а затем воспроизводит их позже, притворяясь вами. По тем же причинам JWT всегда следует обмениваться через безопасный уровень, такой как HTTPS.
источник
Содержимое веб-токена json (JWT) не является безопасным по своей сути, но есть встроенная функция для проверки подлинности токена. JWT - это три хэша, разделенных точками. Третья подпись. В системе с открытым / закрытым ключом эмитент подписывает подпись токена закрытым ключом, который может быть проверен только его соответствующим открытым ключом.
Важно понимать разницу между эмитентом и верификатором. Получатель токена отвечает за его проверку.
Существует два критических этапа безопасного использования JWT в веб-приложении: 1) отправить их по зашифрованному каналу и 2) проверить подпись сразу после ее получения. Асимметричная природа криптографии с открытым ключом делает возможной проверку подписи JWT. Открытый ключ подтверждает, что JWT был подписан соответствующим закрытым ключом. Никакая другая комбинация клавиш не может выполнить эту проверку, тем самым предотвращая попытки олицетворения. Выполните эти два шага, и мы можем с математической уверенностью гарантировать подлинность JWT.
More reading: Как открытый ключ проверяет подпись?
источник
Давайте с самого начала отрицать:
JWT - это очень современный, простой и безопасный подход, который распространяется на Json Web Tokens. Json Web Tokens - это решение для аутентификации без сохранения состояния. Поэтому нет необходимости хранить какое-либо состояние сеанса на сервере, что, конечно, идеально подходит для спокойных API. API Restful всегда должны быть без сохранения состояния, и наиболее широко используемая альтернатива аутентификации с помощью JWT - просто сохранять состояние входа пользователя в систему на сервере с использованием сеансов. Но тогда, конечно, не следует принципу, согласно которому спокойные API должны быть без сохранения состояния, и поэтому такие решения, как JWT, стали популярными и эффективными.
Итак, теперь давайте узнаем, как на самом деле работает аутентификация с Json Web Tokens. Предполагая, что у нас уже есть зарегистрированный пользователь в нашей базе данных. Таким образом, клиент пользователя начинает с отправки запроса с именем пользователя и паролем, затем приложение проверяет, существует ли пользователь, и, если пароль правильный, приложение сгенерирует уникальный веб-токен Json только для этого пользователя.
Токен создается с использованием секретной строки, которая хранится на сервере . Затем сервер отправляет этот JWT обратно клиенту, который сохранит его либо в файле cookie, либо в локальном хранилище.
Точно так же, пользователь проходит аутентификацию и в основном входит в наше приложение, не оставляя никакого состояния на сервере.
Таким образом, сервер на самом деле не знает, какой пользователь на самом деле вошел в систему, но, конечно, пользователь знает, что он вошел в систему, потому что у него есть действующий Json Web Token, который немного похож на паспорт для доступа к защищенным частям приложения.
Итак, еще раз, просто чтобы убедиться, что у вас есть идея. Пользователь входит в систему, как только он получает свой уникальный действующий веб-токен Json, который нигде не сохраняется на сервере. И поэтому этот процесс полностью лишен состояния.
Затем каждый раз, когда пользователь хочет получить доступ к защищенному маршруту, например, к данным своего профиля пользователя. Он отправляет свой веб-токен Json вместе с запросом, так что это похоже на показ его паспорта, чтобы получить доступ к этому маршруту.
Как только запрос попадет на сервер, наше приложение проверит, действительно ли Json Web Token действителен, и если пользователь действительно тот, кем он себя называет, то запрошенные данные будут отправлены клиенту, а если нет, то быть ошибкой, говоря пользователю, что он не имеет доступа к этому ресурсу.
Все это общение должно происходить через https, так что зашифруйте протокол Http, чтобы никто не мог получить доступ к паролям или веб-токенам Json. Только тогда у нас будет действительно безопасная система.
Таким образом, веб-токен Json выглядит как левая часть этого скриншота, который был взят из отладчика JWT в jwt.io, так что по сути это строка кодирования, состоящая из трех частей. Заголовок, полезная нагрузка и подпись. Теперь заголовок - это просто метаданные о самом токене, а полезная нагрузка - это данные, которые мы можем закодировать в токене, любые данные, которые нам действительно нужны. Таким образом, чем больше данных мы хотим закодировать, тем больше JWT. В любом случае, эти две части - просто текст, который будет закодирован, но не зашифрован.
Так что любой сможет их декодировать и читать , мы не можем хранить здесь какие-либо конфиденциальные данные. Но это совсем не проблема, потому что в третьей части, так и в подписи, вещи действительно становятся интересными. Подпись создается с использованием заголовка, полезной нагрузки и секрета, который сохраняется на сервере.
И весь этот процесс называется подписанием веб-токена Json . Алгоритм подписи берет заголовок, полезную нагрузку и секрет для создания уникальной подписи. Так что только эти данные плюс секрет могут создать эту подпись, хорошо? Затем вместе с заголовком и полезной нагрузкой эти подписи образуют JWT, который затем отправляется клиенту.
Как только сервер получает JWT для предоставления доступа к защищенному маршруту, он должен проверить его, чтобы определить, действительно ли пользователь является тем, кем он себя считает. Другими словами, он проверит, если никто не изменил заголовок и данные полезной нагрузки токена. Итак, еще раз, этот шаг проверки проверит, действительно ли никакая третья сторона не изменила ни заголовок, ни полезную нагрузку веб-токена Json.
Итак, как на самом деле работает эта проверка? Ну, это на самом деле довольно просто. Как только JWT получен, проверка получит свой заголовок и полезную нагрузку и вместе с секретом, который все еще сохраняется на сервере, в основном создаст тестовую подпись.
Но оригинальная подпись, которая была сгенерирована при первом создании JWT, все еще находится в токене, верно? И это ключ к этой проверке. Потому что теперь все, что нам нужно сделать, это сравнить тестовую подпись с исходной подписью. И если тестовая подпись совпадает с исходной подписью, то это означает, что полезная нагрузка и заголовок не были изменены.
Потому что если бы они были изменены, то подпись теста должна была бы быть другой. Следовательно, в этом случае, когда данные не были изменены, мы можем затем аутентифицировать пользователя. И, конечно, если две подписи на самом деле разные, ну, значит, кто-то подделал данные. Обычно пытаясь изменить полезную нагрузку. Но эта третья сторона, управляющая полезной нагрузкой, конечно, не имеет доступа к секрету, поэтому они не могут подписать JWT. Таким образом, оригинальная подпись никогда не будет соответствовать манипулируемым данным. И поэтому в этом случае проверка всегда будет неудачной. И это ключ к созданию всей этой системы. Это магия, которая делает JWT настолько простым, но и чрезвычайно мощным.
источник
Только privateKey JWT, который находится на вашем сервере, расшифровывает зашифрованный JWT. Те, кто знает privateKey, смогут расшифровать зашифрованный JWT.
Скрывайте приватный ключ в безопасном месте на вашем сервере и никогда никому не сообщайте о приватном ключе.
источник
Для людей, которые не могут позволить себе дорогостоящие запросы к базе данных, как я, один из вариантов сохранения конфиденциальных данных (привилегии пользователей и т. Д.) Заключается в том, что при создании JWT вы можете зашифровать эти данные и прикрепить их к токену JWT. (Храните ключ шифрования в бэкэнде)
Если вы хотите прочитать конфиденциальную информацию, вы можете отправить токен JWT на сервер, расшифровать его и получить информацию обратно. Таким образом, вам не нужно выполнять поиск в БД или получать конфиденциальную информацию в интерфейсе через токен JWT.
источник
Я бы посоветовал взглянуть на JWE, используя специальные алгоритмы, которых нет в jwt.io для расшифровки
Ссылочная ссылка: https://www.npmjs.com/package/node-webtokens
Этот ответ может быть слишком запоздалым, или вы, возможно, уже нашли способ, но, тем не менее, я чувствовал, что это будет полезно и для вас, и для других.
Простой пример, который я создал: https://github.com/hansiemithun/jwe-example
источник