Skip to content

Instantly share code, notes, and snippets.

@kristianlm
Last active January 31, 2016 09:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kristianlm/8c7b4eddb697cd4d0daa to your computer and use it in GitHub Desktop.
Save kristianlm/8c7b4eddb697cd4d0daa to your computer and use it in GitHub Desktop.
(use matchable hmac sha2 base64 tweetnacl)
(define (base64url-decode m) (base64-decode (string-translate m "-_" "+/")))
(define (base64url-encode m)
(string-trim-right ;; remove = padding (not used/needed in jwt)
(string-translate (base64-encode m) "+/" "-_") #\=))
(define (hs256 secret) (hmac secret (sha256-primitive)))
;; b64header ignored! (read https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/)
(define (jwt-hs256-verify jwt secret)
(match (string-split jwt ".")
((b64header b64payload b64signature)
(and (string=
(base64url-decode b64signature) ;; not zero-padded
((hs256 secret) (string-append b64header "." b64payload)))
(base64url-decode b64payload)))))
(define (jwt-hs256-sign payload-string secret)
(let* ((b64header (base64url-encode "{\"alg\":\"HS256\",\"typ\":\"JWT\"}"))
(b64payload (base64url-encode payload-string))
(signed (string-append b64header "." b64payload))
(b64signature (base64url-encode ((hs256 secret) signed))))
(string-append signed "." b64signature)))
;; from https://jwt.io/#debugger
(define jwt "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ")
(print "trusted payload: " (jwt-hs256-verify jwt "secret"))
(let ((payload "{\"cake\":true}"))
(print "jwt-hs256 token for " payload ": " (jwt-hs256-sign payload "secret")))
;; alg:ed25519 works too!
(use tweetnacl)
(define (jwt-ed25519-verify jwt pk)
(match (string-split jwt ".")
((b64header b64payload b64signature)
;; todo: use 'kid' from header and match pk
(and ((asymmetric-verify (string->blob pk))
(string-append (base64url-decode b64signature)
b64header "." b64payload))
(base64url-decode b64payload)))))
;; from https://github.com/bryanjos/joken/blob/master/test/support/keys_fixture.exs
(define pk (base64url-decode "l11mBSuP-XxI0KoSG7YEWRp4GWm7dKMOPkItJy2tlMM"))
(define jwt "eyJhbGciOiJFZDI1NTE5IiwidHlwIjoiSldUIn0.eyJuYW1lIjoiSm9obiBEb2UifQ.9a7z_qCuHwBMVSOG9sDzc2Ccbk49tY2GLddqViz0nuB4zG9pQS-jhhGpkYwQ9LE33742__nujzWLaSJ93tYhAw")
(print "trusted ed25519 payload: " (jwt-ed25519-verify jwt pk))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment