2015-04-04 46 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); 
    } 
};