6
$\begingroup$

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?

$\endgroup$

1 Answer 1

6
$\begingroup$

I stole the HMAC from here https://mathematica.stackexchange.com/a/167636/72682. The header/payload/secret are the same as the ones on the Wikipedia page https://en.wikipedia.org/wiki/JSON_Web_Token. Thanks to the suggestions in @WReach's comment I was able to get the same token in the Wikipedia article.

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" *) 
$\endgroup$
2
  • 2
    $\begingroup$ +1. You can get the exact result from the Wikipedia article if you: 1) use ExportString[..., "JSON", "Compact"->True] to suppress pretty-printing and 2) use Developer`EncodeBase64[...] instead of ExportString[..., "Base64"] to suppress newlines in the token. $\endgroup$ Commented Jun 17, 2020 at 2:27
  • $\begingroup$ Wonderful! Thank you so much for your answer. $\endgroup$ Commented Jun 17, 2020 at 16:04

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.