#encryption #jwt #elixir
#шифрование #jwt #elixir
Вопрос:
Я пытаюсь создать токены JWS с помощью Elixir. Что у меня есть:
- Закрытый ключ RSA
- Отпечаток пальца сертификата sha256 в кодировке Base 64
- Заголовок токена
- Тело токена
Что мне нужно:
- Подпись токена
Заголовок JWS выглядит следующим образом
{
"x5t#S256": {{ cert thumbprint }},
"alg":"RS256"
}
Чтобы получить токен заголовка, я просто конвертирую его в base64, и все готово. То же самое с телом токена, я просто конвертирую полезную нагрузку в base64.
Проблема заключается в получении подписи токена. Насколько я понимаю, это должно быть сделано следующим образом:
token signature = base64(rsa-sha256(token header "." token body))
Q1: Правильна ли моя логика здесь?
Q2: Как выполнить шифрование rsa-sha256 в Elixir? Или это то же самое, что :crypto.hash(sha256, ...)
?
Комментарии:
1. Зачем вам изобретать велосипед? Для этого у нас есть
JOSE
. Даже если вы не хотите полагаться на стороннюю версию, проверьте код, это OSS, там есть все алгоритмы.
Ответ №1:
Я не работал с JWS в Elixir, но я решил попробовать это в качестве упражнения. Вы можете сгенерировать подпись JWS с помощью RSA следующим образом:
rsa_private_key = JOSE.JWK.from_pem_file("rsa-2048.pem")
header = %{"alg" => "RS256"}
payload = %{"example" => "foo"}
JOSE.JWT.sign(rsa_private_key, header, payload)
Вывод:
{%{alg: :jose_jws_alg_rsa_pkcs1_v1_5},
%{
"payload" => "eyJleGFtcGxlIjoiZm9vIn0",
"protected" => "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9",
"signature" => "T2llXS2pGN-jev10Xd5EZQmaEih_dn9DIn5FJJg8ocEwIpNLupEWiNLz-5mP21z9JGpyYPFaRuq77AtKL67nP7KMDTpKKYJonOxQdL31sHU4vTKBRf-2XcVbDLGkST5dUMUWHOS106Sw_0x7DSiuFBUzkkYQ_lZKES8idVUp88Kx4uWU65Yoti0_Pu7aVLRGWDu0EiMjzuTPTBkMoib21VEVBqrJ4jiKXFudEFiNNSaV_GOH9yNZqyxwl4RhCYYT9U-Mda8Dc7xPjQk0LaJhwlaV91OhxJQHP2fGR8XkznHFlRRHTEsesYgl9OKZuSzVXoffydLc1VotphKUnG1WZQ"
}}
И если вы хотите это в краткой форме:
JOSE.JWT.sign(rsa_private_key, header, payload) |> JOSE.JWS.compact
Производит:
{%{alg: :jose_jws_alg_rsa_pkcs1_v1_5},
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleGFtcGxlIjoiZm9vIn0.T2llXS2pGN-jev10Xd5EZQmaEih_dn9DIn5FJJg8ocEwIpNLupEWiNLz-5mP21z9JGpyYPFaRuq77AtKL67nP7KMDTpKKYJonOxQdL31sHU4vTKBRf-2XcVbDLGkST5dUMUWHOS106Sw_0x7DSiuFBUzkkYQ_lZKES8idVUp88Kx4uWU65Yoti0_Pu7aVLRGWDu0EiMjzuTPTBkMoib21VEVBqrJ4jiKXFudEFiNNSaV_GOH9yNZqyxwl4RhCYYT9U-Mda8Dc7xPjQk0LaJhwlaV91OhxJQHP2fGR8XkznHFlRRHTEsesYgl9OKZuSzVXoffydLc1VotphKUnG1WZQ"}
Вот открытый ключ, если вы хотите его проверить:
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAtRPXSP1W 5sgVLeRFYrrF6L7 gaEkPOWV2FDtPL/vRQH77bicJYb
oVytE/8JyHj8kH24hxwCy2LFl5fZLaIrqYBy1B1t8LtxTRVhi3JIc76IGZ3dfxrz
Dnv94Vu9BRxE7y37f7w8ulDVlGpmJhfCIMj8SYJrFWgHlQB2u7c/B43RE6uphRfD
nr4FkJ3ChUFKhuVZHm27r5/CllHNhMejA/WawtlWKdU33In1Xp2O GxjLKoYuGGQ
U9MdrismDtn6bVcq5K97bByxelJel2rUG4sbtQk01gVtfun63rSzOP9EkNJOoRll
YDm3HQlDUY7 D9AMG3XlQuR7tlDXQtGIJQIDAQAB
-----END RSA PUBLIC KEY-----
Комментарии:
1. Спасибо за ваш ответ. Заголовок JWS, который у меня есть, является
%{ "x5t#S256" => "C7DFYPKmoE6Ul8ZbpVohJXBPOUoXsgSki5kkaQKP1nc", "alg" => "RS256" }
и конечным результатом для этого должен бытьeyJ4NXQjUzI1NiI6IkM3REZZUEttb0U2VWw4WmJwVm9oSlhCUE9Vb1hzZ1NraTVra2FRS1AxbmMiLCJhbGciOiJSUzI1NiJ9
, но он не работает с использованием вашего метода.2. Конечно, это так, просто замените
header
на то, что вам нужно. Вот JWT (подписанный моим ключом) с этим заголовком, использующий тот же код: gist.githubusercontent.com/adamu /…3.Я заметил, что эта библиотека добавляет
%{ "typ" => "JWT" }
к заголовку — возможно, это вызывает у вас проблемы?
Ответ №2:
смотрите этот пример на JWT Auth с Elixir на Phoenix
используя :bcrypt_elixir
, и :guardian