racket - Sha256 and URI encoding woes -


i trying port function javascript/node racket

var crypto = require("crypto");    function getauthorizationtokenusingmasterkey(verb, resourcetype, resourcelink, date, masterkey) {       var key = new buffer(masterkey, "base64");        var text = (verb || "").tolowercase() + "\n" +                (resourcetype || "").tolowercase() + "\n" +                (resourcelink || "") + "\n" +                date.tolowercase() + "\n" +                "" + "\n";        var body = new buffer(text, "utf8");       var signature = crypto.createhmac("sha256", key).update(body).digest("base64");        var mastertoken = "master";        var tokenversion = "1.0";        return encodeuricomponent("type=" + mastertoken + "&ver=" + tokenversion + "&sig=" + signature);   } 

```

this gets few strings, concats creates sha256 hash them , @ end encodes uri representation.

here racket version sadly not yield same results js version one. 1 last encoding uri missing have suspicion sha256 code isnt right.

#lang racket  (require sha) (require threading) (require net/base64) (require (rename-in grommet/crypto/base64                     (base64-encode encode)                     (base64-decode decode)))  (define (auth-token master-key date [verb ""] [res-type ""] [res-link ""])       (~>> (list verb res-type res-link date)         (map string-downcase)         (string-join _ "\n" #:after-last "\n")         string->bytes/utf-8         (hmac-sha256 (string->bytes/utf-8 master-key))         encode         (format "type=master&ver=1.0&sig=~a")))  (define x (auth-token "master" "das ist ein datum")) 

edit tried boil down example can see wrong , here got

;; racket (encode (hmac-sha256 (decode "master")(string->bytes/utf-8 "payload")))  ;; => psfwnl7wuipzwhmyb9ji891sgmmhjauj3e0e/d5v46c="  //javascript crypto.createhmac("sha256", "master").update("payload").digest("base64");   //=> 'xlpqbputenlganhdb4ebs7dlfe2je1d5mo6vjnqjhgi=' 

solution

(define (auth-token3 master-key date [verb ""] [res-type ""] [res-link ""])     (let* ([! string-downcase] [->bytes string->bytes/utf-8])         (~>> (list (! verb) "\n" (! res-type) "\n" res-link "\n" (! date) "\n\n")             string-append*             ->bytes             (hmac-sha256 (base64-decode (->bytes master-key)))             base64-encode             (format "type=master&ver=1.0&sig=~a")             string-trim             uri-encode))) 

your boiled-down example should be

(encode (hmac-sha256 (string->bytes/utf-8 "master")(string->bytes/utf-8 "payload")))

not

(encode (hmac-sha256 (decode "master")(string->bytes/utf-8 "payload")))

the former version returns correct result.

a possible flaw (map string-downcase) on text components, whereas js function not call tolowercase on resourcelink. try this:

(define (auth-token master-key date [verb ""] [res-type ""] [res-link ""])   (let* ([! string-downcase] [->bytes string->bytes/utf-8]          [text/list  (list (! verb) "\n" (! res-type) "\n" res-link "\n" (! date) "\n")]          [text/bytes (->bytes (string-append* text/list))]          [signature  (encode (hmac-sha256 (->bytes master-key) text/bytes))])     (string-append "type=master&ver=1.0&sig=" signature))) 

the js version ends calling encodeuricomponent. don't know there doesn't seem equivalent in code


Comments