我正在使用keybase.io API - 尝试从javascript驱动它。登录是一个两步过程。第二步详述如下 https://keybase.io/docs/api/1.0/call/login
我被困在下面;
服务器和客户端共享此密钥,并为客户端共享 要成功登录用户,必须证明这一点 服务器的秘密。为了防止重放攻击,它确实如此 不发送秘密本身。相反,它将pwh视为MAC密钥,并且 MAC是上一步中检索到的临时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参数(这是我从上一步使用密钥库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()
答案 0 :(得分:2)
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);
}
};