2

我正在使用 keybase.io API - 试图从 javascript 驱动它。登录是一个两步过程。第二步在 https://keybase.io/docs/api/1.0/call/login中有详细说明。

我被困在以下问题上;

服务器和客户端共享这个秘密,为了让客户端成功登录用户,它必须向服务器证明知道这个秘密。为了防止重放攻击,它本身不发送秘密。相反,它将 pwh 视为 MAC 密钥,并对上一步中检索到的临时 login_session 进行 MAC 处理:

hmac_pwh = HMAC-SHA512(pwh, base64decode(login_session)) 

两个输入都是二进制格式;pwh 密钥是从上面的 scrypt 以二进制格式输出的,login_session 经过 base64 解码,然后以二进制形式输入 HMAC。

我正在使用 CryptoJS 库,它提供了以下实现示例

 var hash = CryptoJS.HmacSHA256('Message','Secret Passphrase');

我有几个问题;

  1. 作为术语,“MAC 密钥”是否等于“秘密密码”,因此 CryptoJS 函数参数的顺序与 Keybase 上给出的代码示例相反?

  2. 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()
    
4

1 回答 1

2

CryptoJS.HmacSHA256()高兴地把自己WordArray当作钥匙。因此,您只需要将您的转换UInt8Array为 CryptoJS' WordArray

这篇文章提供了这样一个由 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);
    }
};
于 2015-04-04T17:43:38.523 回答