Message Boards Message Boards

[Solved] What is the best way to generate a JSON Web Token (JWT)?

Posted 4 years ago

I want to access a service that uses JWT authentication for its API. Generating a JWT doesn't look too difficult, it is a combination of BASE64URL encoding, and HMAC Signing. However, these things can be a finicky to get right, so I was wondering if anyone had done this in Mathematica? For instance, is it possible to use the SecuredAuthenticationKey function to do what I need?

POSTED BY: Andrew Burnett
6 Replies
Posted 4 years ago

Thanks Rohit. I have also updated my answer to bring everything in one place.

POSTED BY: Andrew Burnett
Posted 4 years ago

Crossposted here.

POSTED BY: Rohit Namjoshi

Hi Andrew. The code above works? Do you have the link to StackExchange reference?

POSTED BY: Rodrigo Murta
Posted 4 years ago

User Flinty over at mathematica.stackexchange.com came up with a great answer.

hmacFnew[method_, message_, key_] := 
 Module[{dkey, dmsg, opad, ipad, blocksize}, 
  blocksize = If[method === "SHA384" || method === "SHA512", 128, 64];
  {dkey, dmsg} = StringToByteArray /@ {key, message};
  If[Length[dkey] > blocksize, dkey = Hash[dkey, method, "ByteArray"]];
  dkey = Normal[dkey];
  If[Length[dkey] < blocksize, dkey = PadRight[dkey, blocksize, 0]];
  {opad, ipad} = ByteArray[BitXor[dkey, ConstantArray[#, blocksize]]] & /@ {92, 54};
  Hash[Join[opad, Hash[Join[ipad, dmsg], method, "ByteArray"]], method, "Base64Encoding"]]

urlfixb64[b64_?StringQ] := 
 StringReplace[StringSplit[b64, "="][[1]], {"+" -> "-", "/" -> "_"}]

secret = "secretkey";
header = <|"alg" -> "HS256", "typ" -> "JWT"|>;
payload = <|"loggedInAs" -> "admin", "iat" -> 1422779638|>;
headerJSON = ExportString[header, "JSON", "Compact" -> True];
payloadJSON = ExportString[payload, "JSON", "Compact" -> True];
header64 = Developer`EncodeBase64[headerJSON] // urlfixb64;
payload64 = Developer`EncodeBase64[payloadJSON] // urlfixb64;
signature = hmacFnew["SHA256", header64 ~~ "." ~~ payload64, secret] // urlfixb64;
token = header64 ~~ "." ~~ payload64 ~~ "." ~~ signature

(* result: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI" *)
POSTED BY: Andrew Burnett
Posted 4 years ago

Hmmm, looks like this has not been tried before. OK, I shall dive in and report back

POSTED BY: Andrew Burnett
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract