javascript - 在 Javascript 中实现 Keybase 的 HMAC-SHA256

标签 javascript cryptography hmac cryptojs keybase

我正在使用 keybase.io API - 尝试从 javascript 驱动它。登录过程分为两步。第二步详细介绍在 https://keybase.io/docs/api/1.0/call/login .

我陷入了以下困境;

The server and the client share this secret, and for the client to successfully log the user in, it must prove knowledge of this secret to the server. To protect against replay attacks, it does not send the secret itself. Rather, it treats pwh as MAC key, and MACs the temporary login_session retrieved in the previous step:

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

Both inputs are in binary format; the pwh key was output in binary format from scrypt above, and the login_session is base64-decoded and then fed into HMAC in binary.

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

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

我有几个问题;

  1. 就术语而言,“MAC key ”是否等于“ secret 密码”,因此 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()
    

最佳答案

CryptoJS.HmacSHA256() 很乐意将自己的 WordArray 作为 key 。因此,您只需将 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);
    }
};

关于javascript - 在 Javascript 中实现 Keybase 的 HMAC-SHA256,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29448968/

相关文章:

javascript - 全局变量在下面的 javascript 函数中未定义

javascript - 是否可以一次绑定(bind)多种类型的数据?

c# - 无法使用 MimeKit 解密 p7m

Delphi - 无法让 HMAC-SHA256 通过 RFC 4231 测试向量

c# - 在多个客户端使用它的情况下保护 ASP.NET Web API 2 的最佳方法

javascript - 我可以使用 jquery 字符串来定位 id 吗?

javascript - jQuery .hide 方法在 td 上不起作用?

c++ - 如何将 CAPI 的 CryptImportKey 与来自 OpenSSL 的 PEM 编码公钥一起使用?

java - 如何在 Android Studio 中使用与该函数无关的函数中的数组

ruby - 在 Ruby 中生成 JWT