2015-04-04 186 views
2

我正在使用keybase.io API--试图从JavaScript驱动它。登录是一个两步过程。第二步详述于 https://keybase.io/docs/api/1.0/call/login在Javascript中为Keybase实现HMAC-SHA256

我被困在以下;

服务器和客户端共享这个秘密,并为客户 成功登录的用户,就必须证明这一点 秘密到服务器的知识。为了防止重播攻击,它不会自己发送秘密。相反,它把作为PWH MAC密钥,和 MAC的在上一步中检索到的临时login_session:

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

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

我使用CryptoJS库,给出了实施下面的例子

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

我有几个问题;

  1. 作为术语的问题是“MAC密钥”等于“秘密密码短语”并且因此CryptoJS功能参数在它们的顺序VS上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() 
    

回答

2

CryptoJS.HmacSHA256()愉快地需要自己的WordArray作为重点。所以你只需要将你的UInt8Array转换成CryptoJS'WordArray

post提供由蒙特拉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); 
    } 
};