2016-07-26 4 views
4

Я внедряю систему знака с помощью схемы JWT (JsonWebToken). В основном после входа пользователя в систему/входа в систему сервер подписывает JWT и передает его клиенту.Общие сведения о подписании RSA для JWT

Клиент затем возвращает токен с каждым запросом, а сервер проверяет токен перед отправкой ответа.

Это в значительной степени то, как вы ожидали бы этого, но у меня есть некоторые проблемы с логикой процесса. Из всех математических статей, которые я прочитал, кажется, что RSA-подписка использует асимметричные ключи для подписи. Поскольку открытый ключ, как следует из его названия, подвергается клиенту, а закрытый ключ хранится на сервере, имеет смысл подписывать JWT с открытым ключом, который отправляется клиенту и проверяет его на стороне сервера, используя закрытый ключ.

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

ответ

11

Прежде всего, извинения, этот ответ получил довольно длинный характер.

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

Итак, зачем вам публичный/закрытый ключ для JWT? Ну, во-первых, вам не нужно использовать общедоступный/закрытый ключ.

Вы можете кодировать JWT с несколькими различными алгоритмами, RSA является одним из них. Другим популярным выбором для кодирования ваших JWT являются алгоритмы ECDSA или HMAC (стандарт JWT поддерживает others as well). HMAC, в частности, не является схемой открытого/закрытого ключа. Есть только один ключ: ключ, который используется для шифрования и дешифрования токенов. Вы можете подумать об этом, используя частный ключ для подписания и дешифрования JWT. Я не эксперт по этому поводу, но вот выводы, которые я недавно сделал для своих собственных исследований:

Использование HMAC является приятным, потому что это самый быстрый вариант. Тем не менее, чтобы расшифровать JWT, вам нужно дать кому-то один ключ, который делает все. Совместное использование этого ключа с кем-то другим означает, что этот человек теперь может также подписать токенов и притворяться, будто они вы. Если вы создаете несколько серверных приложений, которые все должны иметь возможность проверять ваши JWT, вы можете не захотеть, чтобы каждое приложение также имело возможность кодировать токены (разные программисты могли поддерживать различные приложения, используя возможности encypting с большим количеством люди - это риск для безопасности и т. д.). В этом случае лучше иметь один закрытый закрытый ключ (и одно приложение, которое подписывается), а затем делиться открытым ключом с другими людьми, чтобы дать им возможность проверить токены.Здесь секретный ключ используется для шифрования токенов, а открытый ключ используется для их дешифрования. В этом случае вам нужно выбрать RSA или ECDSA.

В качестве примера у вас может быть экосистема приложений, которые все подключаются к той же базе данных. Чтобы регистрировать пользователей, каждое приложение отправляет людей в один, , посвященный приложению «вход в систему». Это приложение имеет закрытый ключ. Другие приложения могут подтвердить, что пользователь зарегистрирован с использованием открытого ключа (но они не могут регистрировать пользователей).

Исследование, которое я наметил, указывает на то, что RSA является лучшим вариантом для большинства приложений JWT в этом scenerio. Это потому, что ваше приложение будет теоретически проверять токены часто. RSA намного быстрее, чем ECDSA при проверке. ECDSA в первую очередь хороша, потому что ключи меньше по размеру. Это делает его лучше для https-сертификатов, потому что вам нужно отправить открытый ключ в браузер клиента. Однако в JWT scenerio ключи остаются на сервере, поэтому размер хранилища не определен, и скорость проверки важнее.

Заключение: если вы создаете небольшое приложение без нескольких небольших приложений для микросервиса/вы единственный разработчик, вероятно, выберите HMAC для шифрования ваших ключей. В противном случае, вероятно, выберите RSA. Опять же, я не эксперт, просто кто-то, кто недавно искал эту тему, так что возьмите это с солью.

2

Ваше предложение:

смысл подписать JWT с помощью открытого ключа, который посылается клиенту и проверить его на стороне сервера с помощью закрытого ключа.

Неправильная версия. Подписание выполняется с помощью закрытого ключа сервера, шифрование выполняется с помощью открытого ключа клиента. Вот как работает PKI в целом.

+0

Итак, акт подписания на самом деле не является актом шифрования? –

+0

акт подписания - это акт шифрования подписи, а не самого сообщения, см .: http://stackoverflow.com/questions/454048/what-is-the-difference-between-encrypting-and-signing-in- асимметричное шифрование –