Генерация токенов JWS в Elixir

#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