【问题标题】:Implementing HMAC-SHA256 for Keybase in Javascript在 Javascript 中为 Keybase 实现 HMAC-SHA256
【发布时间】:2015-04-04 16:48:10
【问题描述】:
我正在使用 keybase.io API - 试图从 javascript 驱动它。登录是一个两步过程。第二步详述于
https://keybase.io/docs/api/1.0/call/login.
我被困在下面;
服务器和客户端共享这个秘密,并为客户端
要成功登录用户,它必须证明知道这一点
服务器的秘密。为了防止重放攻击,它确实
不发送秘密本身。相反,它将 pwh 视为 MAC 密钥,并且
MACs 上一步检索到的临时 login_session:
hmac_pwh = HMAC-SHA512(pwh, base64decode(login_session))
两个输入都是二进制格式; pwh 密钥以二进制形式输出
来自上面的 scrypt 格式,并且 login_session 是 base64 解码的
然后以二进制形式输入 HMAC。
我正在使用 CryptoJS 库,它提供了以下实现示例
var hash = CryptoJS.HmacSHA256('Message','Secret Passphrase');
我有几个问题;
作为术语,“MAC 密钥”是否等于“秘密密码”,因此 CryptoJS 函数参数的顺序与 Keybase 上给出的代码示例相反?
-
CryptoJS 示例具有纯 ascii 输入,而 Keybase 上的说明是提供二进制输入。当我尝试为它提供一个 uint8array 参数(这是我在使用 keybase API 的上一步中得到的)时,它如下所示;
TypeError: g.clamp is not a function
e,m=4*h;
g.sigBytes>m&&(g=f.finalize(g));
g.clamp();
for(var r=this._oKey=g.clone()
【问题讨论】:
标签:
javascript
cryptography
hmac
cryptojs
keybase
【解决方案1】:
CryptoJS.HmacSHA256() 愉快地将自己的WordArray 作为密钥。所以你只需要将你的UInt8Array 转换为 CryptoJS 的WordArray。
这个post 提供了这样一个由 Vincenzo Ciancia 创建的(未经测试的)转换器:
CryptoJS.enc.u8array = {
/**
* Converts a word array to a Uint8Array.
*
* @param {WordArray} wordArray The word array.
*
* @return {Uint8Array} The Uint8Array.
*
* @static
*
* @example
*
* var u8arr = CryptoJS.enc.u8array.stringify(wordArray);
*/
stringify: function (wordArray) {
// Shortcuts
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
// Convert
var u8 = new Uint8Array(sigBytes);
for (var i = 0; i < sigBytes; i++) {
var byte = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
u8[i]=byte;
}
return u8;
},
/**
* Converts a Uint8Array to a word array.
*
* @param {string} u8Str The Uint8Array.
*
* @return {WordArray} The word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.enc.u8array.parse(u8arr);
*/
parse: function (u8arr) {
// Shortcut
var len = u8arr.length;
// Convert
var words = [];
for (var i = 0; i < len; i++) {
words[i >>> 2] |= (u8arr[i] & 0xff) << (24 - (i % 4) * 8);
}
return CryptoJS.lib.WordArray.create(words, len);
}
};