Sha256 和 URI 编码问题
Sha256 and URI encoding woes
我正在尝试将此功能从 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);
}
```
这会获取一些字符串,将它们连接起来,为它们创建一个 sha256 哈希,最后对所有内容进行编码以表示 URI。
这是我的球拍版本,遗憾的是它没有产生与 JS 版本相同的结果。
对于一个 URI 的最后编码丢失,但我也怀疑 sha256 代码不正确。
#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"))
编辑
我试图归结这个例子,这样我就可以看到哪里出了问题,这就是我得到的
;; racket
(encode (hmac-sha256 (decode "master")(string->bytes/utf-8 "payload")))
;; => pSfWnL7WUIpZwHmYB9JI891SgmMHJauJ3e0E/D5V46c="
//javascript
crypto.createHmac("sha256", "master").update("payload").digest("base64");
//=> 'xlPQBpUTEnLGanhDb4ebS7DlFE2jE1d5mO6VjnqjhgI='
解决方案
(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)))
您的简化示例应该是
(encode (hmac-sha256 (string->bytes/utf-8 "master")(string->bytes/utf-8 "payload")))
没有
(encode (hmac-sha256 (decode "master")(string->bytes/utf-8 "payload")))
前版本returns正确结果
一个可能的缺陷是您 (map string-downcase)
覆盖了所有文本组件,而 JS 函数没有在 resourceLink
上调用 toLowerCase
。试试这个:
(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)))
JS版也是调用encodeURIComponent
结束。我不知道那是做什么的,但你的代码中似乎没有任何等效项
我正在尝试将此功能从 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);
}
```
这会获取一些字符串,将它们连接起来,为它们创建一个 sha256 哈希,最后对所有内容进行编码以表示 URI。
这是我的球拍版本,遗憾的是它没有产生与 JS 版本相同的结果。 对于一个 URI 的最后编码丢失,但我也怀疑 sha256 代码不正确。
#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"))
编辑 我试图归结这个例子,这样我就可以看到哪里出了问题,这就是我得到的
;; racket
(encode (hmac-sha256 (decode "master")(string->bytes/utf-8 "payload")))
;; => pSfWnL7WUIpZwHmYB9JI891SgmMHJauJ3e0E/D5V46c="
//javascript
crypto.createHmac("sha256", "master").update("payload").digest("base64");
//=> 'xlPQBpUTEnLGanhDb4ebS7DlFE2jE1d5mO6VjnqjhgI='
解决方案
(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)))
您的简化示例应该是
(encode (hmac-sha256 (string->bytes/utf-8 "master")(string->bytes/utf-8 "payload")))
没有
(encode (hmac-sha256 (decode "master")(string->bytes/utf-8 "payload")))
前版本returns正确结果
一个可能的缺陷是您 (map string-downcase)
覆盖了所有文本组件,而 JS 函数没有在 resourceLink
上调用 toLowerCase
。试试这个:
(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)))
JS版也是调用encodeURIComponent
结束。我不知道那是做什么的,但你的代码中似乎没有任何等效项