Last active
January 31, 2016 09:52
-
-
Save kristianlm/8c7b4eddb697cd4d0daa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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