0
votes

I am trying to create JWS Tokens using Elixir. What I've got:

  • RSA Private key
  • Base 64 encoded sha256 cert thumbprint
  • Token header
  • Token body

What I need:

  • Token signature

JWS header looks like this

{ 
  "x5t#S256": {{ cert thumbprint }},
  "alg":"RS256"
}

To get the header token I just convert it to base64 and it's finished. Same with token body, I just convert the payload to base64.

The problem is getting token signature. As I understand it should be done like this:

token signature = base64(rsa-sha256(token header + "." + token body))

Q1: Is my logic here correct?

Q2: How to do the rsa-sha256 encryption on Elixir? Or is it the same thing as :crypto.hash(sha256, ...)?

2
Why would you reinvent a wheel? We have JOSE for that. Even if you don’t want to rely on 3rd party, check the code, it is OSS, there are all the algorithms. - Aleksei Matiushkin

2 Answers

1
votes

I've not worked with JWS in Elixir, but I decided to try it as an exercise. You can generate the JWS signature using RSA like this:

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)

Output:

{%{alg: :jose_jws_alg_rsa_pkcs1_v1_5},
 %{
   "payload" => "eyJleGFtcGxlIjoiZm9vIn0",
   "protected" => "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9",
   "signature" => "T2llXS2pGN-jev10Xd5EZQmaEih_dn9DIn5FJJg8ocEwIpNLupEWiNLz-5mP21z9JGpyYPFaRuq77AtKL67nP7KMDTpKKYJonOxQdL31sHU4vTKBRf-2XcVbDLGkST5dUMUWHOS106Sw_0x7DSiuFBUzkkYQ_lZKES8idVUp88Kx4uWU65Yoti0_Pu7aVLRGWDu0EiMjzuTPTBkMoib21VEVBqrJ4jiKXFudEFiNNSaV_GOH9yNZqyxwl4RhCYYT9U-Mda8Dc7xPjQk0LaJhwlaV91OhxJQHP2fGR8XkznHFlRRHTEsesYgl9OKZuSzVXoffydLc1VotphKUnG1WZQ"
 }}

And if you want it in short form:

JOSE.JWT.sign(rsa_private_key, header, payload) |> JOSE.JWS.compact

Produces:

{%{alg: :jose_jws_alg_rsa_pkcs1_v1_5},
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleGFtcGxlIjoiZm9vIn0.T2llXS2pGN-jev10Xd5EZQmaEih_dn9DIn5FJJg8ocEwIpNLupEWiNLz-5mP21z9JGpyYPFaRuq77AtKL67nP7KMDTpKKYJonOxQdL31sHU4vTKBRf-2XcVbDLGkST5dUMUWHOS106Sw_0x7DSiuFBUzkkYQ_lZKES8idVUp88Kx4uWU65Yoti0_Pu7aVLRGWDu0EiMjzuTPTBkMoib21VEVBqrJ4jiKXFudEFiNNSaV_GOH9yNZqyxwl4RhCYYT9U-Mda8Dc7xPjQk0LaJhwlaV91OhxJQHP2fGR8XkznHFlRRHTEsesYgl9OKZuSzVXoffydLc1VotphKUnG1WZQ"}

Here is the public key if you want to verify it:

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAtRPXSP1W+5sgVLeRFYrrF6L7+gaEkPOWV2FDtPL/vRQH77bicJYb
oVytE/8JyHj8kH24hxwCy2LFl5fZLaIrqYBy1B1t8LtxTRVhi3JIc76IGZ3dfxrz
Dnv94Vu9BRxE7y37f7w8ulDVlGpmJhfCIMj8SYJrFWgHlQB2u7c/B43RE6uphRfD
nr4FkJ3ChUFKhuVZHm27r5/CllHNhMejA/WawtlWKdU33In1Xp2O+GxjLKoYuGGQ
U9MdrismDtn6bVcq5K97bByxelJel2rUG4sbtQk01gVtfun63rSzOP9EkNJOoRll
YDm3HQlDUY7+D9AMG3XlQuR7tlDXQtGIJQIDAQAB
-----END RSA PUBLIC KEY-----
0
votes

see this example on JWT Auth with an Elixir on Phoenix

using :bcrypt_elixir, and :guardian