Демистификация JWT

    Вокруг JWT сложилась много распространенных заблуждений. Одно из них, например, что JWT зашифровано (на самом деле только подписано и закодировано base64url). На практике, я часто встречаюсь с довольно странными решениями, когда в JWT хранится только один идентификатор сессии (на самом деле если вы работаете с сессией то JWT вам не нужен). Или же в JWT хранится только один идентификатор пользователя, профайл которого запрашивается при каждом запросе из базы данных (на самом деле JWT имеет смысл, если Вы хотите уменьшить количество запросов в базу данных). Или, что еще более странно — сами JWT хранятся в базе данных.


    Одной из объективных причин такого недопонимания роли и места JWT является то, что спецификация JWT описывает формат JWT, и ничего не говорит о том как JWT нужно применять.


    Желание написать об этом у меня возникло уже давно. И после просмотра очередного проекта с немного странным использованием JWT я все же решился.


    Начнем с самой главной демистификации. JWT может выглядеть вот так:


    eyJhbGciOiJSUzI1NiJ9.eyJpcCI6IjE3Mi4yMS4wLjUiLCJqdGkiOiIwNzlkZDMwMGFiODRlM2MzNGJjNWVkMTlkMjg1ZmRmZWEzNWJjYzExMmYxNDJiNmQ5M2Y3YmIxZWFmZTY4MmY1IiwiZXhwIjoxNjA3NTE0NjgxLCJjb3VudCI6MiwidHRsIjoxMH0.gH7dPMvf2TQaZ5uKVcm7DF4glIQNP01Dys7ADgsd6xcxOjpZ7yGhrgd3rMTHKbFyTOf9_EB5NEtNrtgaIsWTtCd3yWq21JhzbmoVXldJKDxjF841Qm4T6JfSth4vvDF5Ex56p7jgL3rkqk6WQCFigwwO2EJfc2ITWh3zO5CG05LWlCEOIJvJErZMwjt9EhmmGlj9B6hSsEGucCm6EDHVlof6DHsvbN2LM3Z9CyiCLNkGNViqr-jkDKbn8UwIuapJOrAT_dumeCWD1RYDL-WNHObaD3owX4iqwHss2yOFrUfdEynahX3jgzHrC36XSRZeEqmRnHZliczz99KeiuHfc56EF11AoxH-3ytOB1sMivj9LID-JV3ihaUj-cDwbPqiaFv0sL-pFVZ9d9KVUBRrkkrwTLVErFVx9UH9mHmIRiO3wdcimBrKpkMIZDTcU9ukAyaYbBlqYVEoTIGpom29u17-b05wY3y12lCA2n4ZqOceYiw3kyd46IYTGeiNmouG5Rb5ld1HJzyqsNDQJhwdibCImdCGhRuKQCa6aANIqFXM-XSvABpzhr1UmxDijzs30ei3AD8tAzkYe2cVhv3AyG63AcFybjFOU8cvchxZ97jCV32jYy6PFphajjHkq1JuZYjEY6kj7L-tBAFUUtjNiy_e0QSSu5ykJaimBsNzYFQ

    Если его декодировать base64url — миф о "секретности" сразу же разрушается:


    {"alg":"RS256"}{"ip":"172.21.0.5","jti":"079dd300ab84e3c34bc5ed19d285fdfea35bcc112f142b6d93f7bb1eafe682f5","exp":1607514681,"count":2,"ttl":10} O2Mrn%!OPzN{hk11l\9Mkd    Z&ۚWJP%^DǞ8޹*X؄և|!䵥C&D0Di?Ak
    nue7bݟB 6AV*9)S.jNv    `EcG9ތ*6kQDv_xzߥEdgbs<wP(Ӂ"?K ?WxiHp<>,/EU]T䒼-Q+\}PfbuȦ
    7�ɦZTJ jhon׿Ӝ-v 6j9ǘ
    :!z#fEewQ*44    bl"&t!F    �*s>]+U&8z-@Fap2p\S܇}0hˣŦy*ԛb1H/A�U3bA$)   j)

    Первая часть в фигурных скобках называется JOSE Header и описана https://tools.ietf.org/html/rfc7515. Может содержать поля, из которых наиболее важное alg. Если задать {"alg":"none"} — токен считается валидным без подписи. И таким образом к Вашему API может получить доступ любой с токеном, сформированным вручную без подписи. В настоящее время большинство библиотек отвергают такие токены по умолчанию, но все же проверьте свои API на всякий случай.


    Вторая часть в фигурных скобках — это полезная нагрузка. Немного неудобно, что в этой части размещаются и пользовательские данные, и стандартные заголовки, например jti — идентификатор токена и exp — срок окончания действия токена. Такие поля как срок окончания действия токена, срок начала действия токена могут проверяться или не проверяться библитеками для работы с JWT — в последнем случае придется в явном виде проверять срок действия на уровне приложения.


    И, наконец, подпись. Подпись может быть сформирована при помощи разных алгоритмов. Наиболее удобно, если алгоритмы основаны на паре ключей (публичном и приватном). Тогда проверку подписи можно проводить публичным ключом, который можно без опасения распространять между серверами, принимающими JWT.


    Таким образом JWT — это просто текст JSON, имеющий криптографическую подпись.


    "Открыв" этот факт, можно поставить вопрос, в каких случаях рационально или не рационально использовать JWT. Можно предположить два основных кейса (если кто-то найдет еще — готов добавить в текст).


    1. Микросервисы. Данные (любые не обязательно авторизация, а например "корзина" с товарами и зафиксированными ценами товаров) формируются и подписываются на одном микросервисе, а используются на другом микросервисе, который проверяет подпись токена публичным ключом.


    2. Авторизация. Этот кейс может быть полезен и для монолита, если нужно сократить количество запросов в базу данных. При реализации "традиционной" сессии каждый запрос API генерирует дополнительный запрос профайла пользователя к базе данных. С JWT все, что берется в базе данных — помещается в JWT и подписывается.



    Поняв это, мы поймем на какое время нужно выпускать JWT — на то время, которое не будет чувствительно, если в исходной информации что-то поменялось, а токен еще действует.


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


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


    Есть рекомендации обновлять "условно-постоянный" токен вместе с выдачей нового авторизационного токена. В этом случае некоторые рекомендуют аннулировать "условно-постоянный" токен сразу после его использования, делая такое использование однократным. В последнем варианте, сессия может прерваться, если сервер зафиксирует выдачу нового токена, но из-за сетевых проблем этот токен не будет получен клиентом.


    Условно-постоянный токен может выпускаться бессрочным или на определенный промежуток времени. На выбор этого параметра влияет необходимость в разлогине клиента после определенного периода неактивности. Если приложению нужно из соображений безопасности сделать разлогин после определенного периода неактивности — нужно именно на это период установить срок действия токена и обновлять условно постоянный-токен при каждом обновлении авторизационного токена. Если же разлогина по таймауту не предусмотрено — условно-постоянный токен не имеет срока действия, и в связи с этим его не нужно перезапрашивать и перевыпускать при каждом запросе нового авторизационного токена. Но все же лучше это сделать, так как требование сделать разлогин по таймауту может возникнуть в любой момент. И если это не предусмотреть изначально, выполнить такое требование будет сложно.


    Я намеренно использовал не общепринятые термины авторизационный токен и условно-постоянный токен. Обычно их называют access token и refresh token.


    Есть одна довольно интересная проблема с аннулированием "условно-постоянных" токенов. Если их выпустить бессрочными — то в случае аннулирования их придется хранить также бессрочно. Если выпускать их на какой-то период — то будет происходить разлогин из "вечной" сессии, если за время действия токена не будет обращения к API.


    apapacy@gmail.com
    9 декабря 2020 года

    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 41

      0
      Для этого формируется реестр (например в Redis) аннулированных токенов.
      Для того, чтобы создать такой реестр заранее, надо где-то хранить все выданные токены, а их не хранят. Или придётся создавать запись в реестре по факту прихода запроса с аннулируемым токеном, но зачем это делать, ведь можно просто возвращать ответ о необходимости обновления токена?
      Таким образом, это будет не реестр конкретных токенов, а запись о том, что все токены конкретного пользователя, выданные ранее определённого времени, надо считать недействительными.
        0
        Зачем хранить все выданные токены, если внутри них есть дата окончания и они подписаны. Вот именно, что можно хранить только НЕИСТЕКШИЕ и ОТОЗВАННЫЕ токены. Как только у отозванного токена истекает время его можно безболезненно удалить из хранилища.
        С другой стороны обычно из-за безопасности хранят все токены. Это нужно для того, чтобы при запросе пользователя о разлогинивании отовсюду, все активные токены сразу отозвать. (Или логика от обратного — если токена нет в базе активных, значит он отозван).
          0

          Разлогин это отдельная тема. Бывает нужно ещё иметь возможность разлогинить с одного устройства все сессии. Тут мне кажется целесообразно все же хранить id сессии. И удалять при разлогине. В реестр аннулированных будет внесен такой sid а не userId

            0
            Внутри токена всегда должен быть jti — уникальный идентификатор этого токена, сохранять нужно только его.
              0

              Смысл сообщения что сохранять вообще ничего не нужно. Зачем нужно сохранять jti? Что с ним делать дальше?

                0
                По простому — это и есть sid сессии.
                  0

                  У самого была такая мысль. Но все же один sid может быть у нескольких токенов которые переиздаются по окончанию срока действия. И тогда не совсем правильно называть его идентификатором. Если в системе выдается на один логин один бессрочный токен то сессия как бы и идентификатор это одно и то же

                  +3

                  Мне кажется в стандарте явно не указаны примеры "правильных" использований JWT т.к. это своего рода просто стандартизированный контейнер. А сама реализация, набор данных и т.д. — является инженерной задачей, относящейся к конкретной сфере применения. Есть разные задачи с разными подходами применения JWT и наборами данных.


                  Например, если речь идёт о коммуникации machine-to-machine (по своей сути микро-сервисы), очевидно, что JWT должны работать на парах ключей, для возможности проверки токена получающей стороной, без уведомления о проверке отправляющей стороны или любой третьей стороны и т.д. Ещё в таких случаях имеет смысл использовать время начала действия токена и наименьшее возможное время жизни токена. Полезная нагрузка токена зависит от назначения сервисов, цели применения токена и т.д.


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


                  Реестр может быть тоже по разному реализован: это может быть Redis с открытым/закрытым доступом, централизованный сервис для проверки валидности токенов (не обязательно выдающий эти токены) или даже открытый, периодически обновляемый файл с перечислением идентификаторов отозванных или активных токенов (в таком случае принимающая сторона может сама проверить отозван ли токен, запросив свободно распространяемый файл с идентификаторами токенов, по принципу проверки подписи через публичные ключи). Очевидно имеет смысл вести реестр именно отозванных токенов (наименьший объём хранимых данных).


                  Можно например сделать отдельный сервис отозванных токенов с двумя точками входа: точкой отзыва токена и открытый, обновляемый файл с идентификаторами отозванных токенов или точкой проверки наличия в реестре идентификатора. При запросе на отзыв токена необходимо передать либо отзываемый токен, либо идентификатор отзываемого токена с какой-то подписью для авторизации операции отзыва (вот ещё один возможный пример использования JWT для отзыва других токенов JWT).


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


                  В таком случае имеет смысл сохранять идентификатор такой сессии в поле jti (вспоминаем, что особых рекомендаций по этому полю нет), таким образом jti (а точнее sid) будет идентифицировать не конкретный токен, а скорее группу связанных токенов. Так же в такой реализации у нас уже будет иметься реест действительных токенов (фактически реестр сессий), причём этот реестр по объёму будет где-то по середине между реестром всех активных токенов и реестром отозванных токенов. Для отзыва всех токенов сессии достаточно будет обновить идентификатор сессии или пересоздать её в реесте.


                  Полезная нагрузка такого токена зависит опять от сферы применения, целей и т.д. Единственное и главное, полезная нагрузка не должна содержать чувствительных данных и желательно не должна содержать часто обновляемых данных (частота обновления выше частоты смены токенов).


                  В итоге "правильных" вариантов использования нет, есть только рекомендации. Каждый разработчик должен сам придумать правильный вариант использования JWT для своих целей, желательно опираясь на рекомендации.


                  Мои примеры тоже не претендуют на единственно верные. Действительно для некоторых случаев использование JWT не даёт никаких преимуществ, возможно просто увеличивает трафик. Однако это вопрос уменьшения объёма трафика или применения стандартизированного контейнера.

                    –2

                    Правильных вариантов нет, но есть неправильные. Неправильный вариант это такой когда разработчик не может сам себе объяснить почему он использует JWT а не сессионный хэш. Чувствтельные данные в JWT хранить не только можно но и нужно. Параллельно необходимо продумать систему отзыва токена до выхода срока его действия.

                      +1

                      Дело в том, что неправильных тоже нет.


                      В конце своего сообщения я указал пример выбора решения использования JWT не смотря на то, что он увеличивает объём трафика и может показаться более жирным чем тупо id + подпись. Главный аргумент — стандартизованный контейнер, об этом даже в самом стандарте написано. JWT это платформо-независимый контейнер токенов, со статусом стандарта. В base64 все вполне умеют в криптографические подписи тоже и в JSON тоже. Его сделали, специально таким гибким и универсальным ведь в большинстве случаев разработка своего формата токенов является задачей сложной, мало сформулировать формат, нужно его внедрить и поддерживать.


                      Если речь идёт о ваших внутренних сервисах, которые разрабатываете вы лично или небольшая команда, очевидно id + подпись вам будет использовать выгоднее (правда не всегда). Но если речь заходит о том, что это экосистема разрабатываемая огромным количеством независимых людей и взаимодействие не ограничивается только лишь вашими сервисами, то JWT тут побеждает как минимум имея статус стандарта, гибкостью и уже имеющейся интеграцией и поддержкой.


                      Потом, в моём примере про хранение сессионного id в jti я не писал, что в токене должен храниться только jti, вы можете вполне туда добавить не чувствительные данные (настоятельно подчёркиваю, что не чувствительные данные) пользователя (например логин, аватар, возможно имя и т.д.), в том числе чтобы снизить нагрузку на базу (это к слову является одним из примеров использования в самом стандарте).


                      Чувствтельные данные в JWT хранить не только можно но и нужно.

                      Вот с этим поспорю и очень даже сильно. Чувствительные данные в токене вы можете хранить, если используете специальную версию JWE с шифрование, но не JWT. JWT является открытым форматом и именно по этому в полезной нагрузке подчёркнуто нельзя хранить чувствительные данные. Отзыв токена не влияет на доступ к этим данным. Они опубликованы открытым текстом (если не учитывать b64). И этот токен может сохраняться где угодно и сколько угодно и вы даже не будете об этом знать. Данные в нём соответственно тоже. Именно по этому в JWT должны храниться только не чувствительные данные.


                      Параллельно необходимо продумать систему отзыва токена до выхода срока его действия.

                      Не во всех сферах и реализациях это необходимо, опять таки мой пример варианта реализации сервиса отзывов JWT. Я там упомянул про использование JWT для отзыва других JWT.


                      А мысль следующая в JWT в поле субъекта указываете id отзываемого токена, время жизни создаваемого токена для авторизации отзыва минимальна, но достаточна на совершение операции. Подпись такого токена производится закрытым ключём клиента, имеющего возможность отзывать токены. Публичный ключ клиента сервису отзывов так или иначе известен. Подпись в данном случае совместно с идентификатором клиента (в поле полезной нагрузки) являются аутентификационными данными клиента, запрашивающего отзыв токена. Причём в авторизационном токене хранить jti не нужно, его просто на просто не нужно отзывать. Сама операция отзыва может быть произведена явно только один раз, т.к. на последующие запросы с этим токеном мы можем ничего не делать (в реестре уже будет идентификатор отзываемого токена). Тут уже помогает время жизни авторизационного токена, можно ещё в нём указать время жизни отзываемого токена.


                      Обращаю внимание реализация зависит от нужд, ни что не является обязательным, если в стандарте явно не указано об этом и не аргументировано.

                        0

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


                        О том что в стандарте не заданы правильные варианты использования JWT я начал в первых абзацах своего сообщения. То что использование любого средства может быть правильным, неправильным и дико неправильным — мне представляется довольно естественным. Тема с JWT выделяется тем, что примеров дико неправильного использования настолько много, что явно выше 50х50,

                          0
                          Я говорю данных чувствительных к изменениям.

                          Вот в этом мы разошлись, я под словом "чувствительные" понимал данные, попадание которых в открытый доступ является проблемой безопасности в том или ином виде. Ровно так же про чувствительность данных в полезной нагрузке трактуется в стандарте, там есть ремарка по поводу использования JWE для этих целей.


                          То что использование любого средства может быть правильным, неправильным и дико неправильным — мне представляется довольно естественным. Тема с JWT выделяется тем, что примеров дико неправильного использования настолько много, что явно выше 50х50

                          Тут вопрос скорее такой, что считать правильным, а что не правильным. JWT даёт возможность самому исполнять для конкретной задачи конкретный вариант реализации. Причём иногда этот вариант со стороны может выглядеть как "дико неправильный", но это со стороны и смотря только на верхушку айсберга, что внизу вы явно не знаете.


                          В конце концов то, что сейчас считается не правильным, через несколько лет может оказаться верным.

                +1

                Для этого лучше использовать Reference-токены.

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

              Данное утвреждение либо неверно высказанно либо неверно понято. JWT RFC явно утвреждает обратное — JWT имеет возможность быть зашифровано (JWE). И эта возможность даже вынесена в отдельный RFC


              Cryptographic algorithms and identifiers for use with this
              specification are described in the separate JSON Web Algorithms (JWA)
              [JWA] specification and an IANA registry defined by that
              specification. Related encryption capabilities are described in the
              separate JSON Web Encryption (JWE) [JWE] specification.
                0

                Имеет возможность быть зашифровано и зашифровано это не одно и то же

                0

                Это и имеется в виду под реестром аннулированных токенов. Важно что это храниться не дольше чем токен и реестр маленький

                  +1
                  закодировано base64
                  наверное всё таки base64url.

                  atob на вашем примере падает (третья часть).
                    0

                    Да, Вы правы сейчас исправлю текст

                    0
                    Почему в примерах микросервисы отдельно, авторизация в монолите отдельно? Авторизация в микросервисах тоже прекрасный кейс.
                    Один (микро) сервис выдает токен для доступа к другому (микро) сервису.
                      0

                      Мне показалось что это будет тавтология. Так как входит в пункт 1.

                      0
                      Или же в JWT хранится только один идентификатор пользователя, профайл которого запрашивается при каждом запросе из базы данных (на самом деле JWT имеет смысл, если Вы хотите уменьшить количество запросов в базу данных)

                      Уменьшение размера JWT важно для уменьшения нагрузки на сеть. Поэтому и кладут id вместо профиля целиком.
                        0

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


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

                          0
                          Поэтому хранить в JWT идентификатор а потом вытягивать данные из базы

                          из кэша.

                          Каждый сам выбирает какой из способов более оптимальный для его конкретной задачи.
                            0

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

                              0
                              Если кэш протух, то откуда взять айдишник пользователя?
                                0

                                JWT также как и кэш может заэкпайрится. В конце концов не кэш управляет разработкой а разработка кэшем.

                            0
                            так как размер подписи не зависит от объема данных а зависит от величины ключа

                            Скорее зависит от применяемого алгоритма подписи. Подпись ведь является по своей сути хешем.

                              0

                              Зависит и от алгоритма и от длины ключа. Я собственно проверял это на практике. Быстрым поиском нашел такое вот обсуждение https://coderoad.ru/6658728/RSA-размер-подписи

                                +1
                                Все таки зависит от размера ключа. А хеш — это входные данные для алгортмов с открытм/закрытым ключем. Притом часть хеша может быть отброшена, если ключи поддерживают меньший размер данных.
                                Например для ECDSA на кривой в 192 бита при хеше 256 бит в подписи будет 192 бит хеша.
                                  0

                                  И всё-таки не зависит от ключа на прямую, но зависит от алгоритма подписи напрямую.


                                  Я именно об этом, ведь если мы используем не пары ключей, а просто секретную строчку и один из алгоритмов HS* — длина подписи будет зависеть только от выбранного алгоритма, но ни как не от длины секретной строчки. Т.к. тут у нас только хеш.


                                  Если мы используем уже пары ключей, тут уже сами алгоритмы зависят от длины ключей согласен. Но сама подпись опять таки в глобальном смысле зависит именно от алгоритма подписи. Ведь даже если мы будем использовать одинаковые ключи (очевидно с одинаковой длинной), но разные алгоритмы (мы же можем использовать как RS512, так и RS256 с одной и той же парой ключей), то длинна подписи будет разной вне зависимости от одинаковой длинны ключей т.к. величина блоков этих алгоритмов разная.


                                  Мы же ведём речь о стандарте JWT в целом, а он поддерживает множество алгоритмов подписей в т.ч. и не на ключах. Если выбрать указанный алгоритм "none", то подпись будет равна длине 0 (т.е. вовсе отсутствовать).

                                    +1
                                    Нет никаких одинаковых ключей при разных алгоритмах. Для каждого алгорима есть свой специфический алгоритм генерации ключей.
                                      0

                                      И даже при использовании любой пары RS* (RSA) — RS256 и RS512? Это же именно алгоритмы генерации подписи JWT, различия между ними в алгоритмах генерации хешей SHA256 и SHA512, но одинаковый алгоритм RSA. Ладно длина будет одна, но ключи можно использовать одинаковые как для RS256, так и для RS512. И опять таки это не противоречит тому, что я пишу — длина подписи JWT зависит именно от алгоритма подписи JWT, алгоритм подписи JWT может работать как с ключами RS*, ES*, PS*, так и без ключей HS* и "none". Если использовать разные ключи одинаковой длинны в разных алгоритмах с одинаковой хеш-функцией (например SHA256) длина подписи будет разная и зависеть от самого алгоритма будь то RSA или ECDSA.

                                        +1
                                        У вас наивное представление об алгоритмах с закрытым/открытым ключем как об симетричных блочных алгоритмах, где используется поосто случайная последовательность. Это не так. Повторю, у кждого алгоритма свои ключи.
                                          0

                                          Опять таки если мы рассматриваем алгоритмы подписи JWT, среди которых есть hash-only HS* (SHA*) и специальный "none" у которых просто нет пар ключей, аргумент про длину подписи зависящую от длины ключа точно так же опровергается. Подчёркиваю я настаиваю именно на утверждении, что подпись JWT зависит от выбранного алгоритма подписи JWT, если это "none" — длина подписи будет равна 0, если это HS* — будет равна размеру хэш-блока, если это RS*, ES*, PS* будет зависеть от длины ключа т.к. длина результата алгоритмов RSA, ECDSA будет зависеть от длины ключа. Но последнее утверждение не применимо к алгоритмам HS* и "none", именно по этому я настаиваю на связи именно от алгоритма подписи JWT. Не стоит откидывать алгоритмы HS* и "none" для них найдутся применения.

                                            0

                                            С Вами по этому поводу н кто не спорит. Зависит от алгоритма и размера ключа все согласны. Как правило используется алгоритм RSA потому что более менее секьюрно хотя стандарт рекомендует эллиптические кривые.

                                          0

                                          К сожалению я далек от алгортмов криптографических. Но их тех воспоминаний когда я ими занимался — минимальный блок, который мы можем получить при алгоритме RSA равен длине ключа. И все блоки кратны длине ключа. наверное в этом дело. Я просто сейчас создал несколько токенов алгоритмом RS256 и выдам результат. Как оказалось подписать этим алгоритмом ключом размером 128 и даже 256 не получается.
                                          Такой токен получается при размере ключа 512


                                          eyJhbGciOiJSUzI1NiJ9.eyJjb3VudCI6MiwiZXhwIjoxNjA3NTU0MDI2LCJpcCI6IjE5Mi4
                                          xNjguNDguNSIsInR0bCI6MTAsImp0aSI6IjlkNWFmZjg1YjBkZWNkOTliOGU5NGE0
                                          YzJmOWZhOGYwZmQyZmQ2YzQzMzJkMTUyZWJjYzA5ZGI2YTUxOGZkNDgifQ.gB
                                          uSqMtN7v_LyGK_6E5GdCoUbvAoaTpA8P9K01_EXNH1Sp6YVnqveSw8TNvzBd5h
                                          mMIN4Bf_UuGhd3QYpG6K4w


                                          а такой при размере 4096


                                          eyJhbGciOiJSUzI1NiJ9.eyJjb3VudCI6MiwidHRsIjoxMCwianRpIjoiZDhiNzViODNkZjg
                                          zY2NlY2Y1NTY3OWI5MTcxN2I5NTA5YWQ2ZTc5NDFmOTBkNjcyOWRkNTI2M2E4
                                          NzAxYmQxOCIsImV4cCI6MTYwNzU1Mzg2NiwiaXAiOiIxOTIuMTY4LjQ4LjUifQ.RkT
                                          PuFo9jKZIQKUSDUEL8qtaNjB1Gm050lj8-Tr1hppOzC7s8OU-
                                          yUt5Ry3KS1OhadCeSq7qIUJmiC9zAN0NQrx1CTuBXbxwf-
                                          qWkknXO7Ob7ejvuvUchTeEDPcNhW5yzTFUp3dbDxKDahyxw7DX7fQBpBYYrFB1
                                          7-s2Jja89BVuU5K6xcJmSCREqj3x326rfebfQSNopxfTzprrLWleM-
                                          3u4JbhXwjMzwrwr8afEi6Tbm-ZeQuCXdwxW8L7I_Lq-
                                          cksUrk0dCp_z4cr32zM6mz6Xuwadg06NCR_hLuuIxC2oyU0Rs6jJsbPCTEup-
                                          uyM5LR3Fw8t8zYMg112GjIHwS0TD9EtWCMRMmytfcpmWMPL8ERHAlAht6v1FC
                                          ohI6Jh5cZZabugVdxhUbmI470arRHusyALeHoE5dj4jNB6vXli3Ce_jrUasEeUE_w3H
                                          93MYSz-msB4Ocr3qMZBsCQBYV2Vcs7mSIuylSKeA4ezjnjePYS_5K3B7U-
                                          HIWkcfRnTan3idMqEZq4BpVSt55jOAlb_5Sg8N9LGfChNkymuHblUWwf0knsacP-
                                          fd1kyClWZtdAS_Ippr8YDjyYAsugHs_IpmW-
                                          AmQbKwYIAc76HMBabc6ZK746PbboJkXKo88nIzZ2AahAQvuFXVReVzuksJzbYakk
                                          _0xPiWhHZLcU6z8

                                            +1
                                            Для RSA сейчас минимум 512 бит, скорее всего поэтому меньшего размера не дают просто сделать.
                              +1

                              Мы используем jwt не для того чтобы не было обращений к бд, а чтобы сервера были stateless и не было необходимости делать shared сессию

                                +1

                                То что вы пишите укладывается в первый кейс который указан в моем тексте.

                                  +2

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

                                Only users with full accounts can post comments. Log in, please.