2015-08-19 52 views
1

我想使用RNCryptor-JS使用SJCL,但由於某種原因,SJCL位數組連接似乎不起作用。SJCL不連接位陣列

var SALT_SIZE = 64/8; 

var plaintext = "Hello, World!"; 

var password = "myPassword"; 

function keyForPassword(password, salt){ 
    // Using CryptoJS for pbkdf2, aes, sha256, and random word arrays 
    var pbkdf2_key = CryptoJS.PBKDF2(
     password, 
     salt, 
     { 
      keySize: 256/32, 
      iterations: 1000, 
      hasher: CryptoJS.algo.SHA256 
     } 
    ); 
    return pbkdf2_key; 
} 

var encryption_salt = CryptoJS.lib.WordArray.random(SALT_SIZE); 
var encryption_key = keyForPassword(password, encryption_salt); 

var hmac_salt = CryptoJS.lib.WordArray.random(SALT_SIZE); 
var hmac_key = keyForPassword(password, hmac_salt); 

var iv = CryptoJS.lib.WordArray.random(128/8); 

var version = sjcl.codec.hex.toBits("03"); 
var options = sjcl.codec.hex.toBits("01"); 

var message = sjcl.bitArray.concat(version, iv); 
message = sjcl.bitArray.concat(message, encryption_salt); 
message = sjcl.bitArray.concat(message, hmac_salt); 
message = sjcl.bitArray.concat(message, iv); 

// Progressive cipher 
var aesEncryptor = CryptoJS.algo.AES.createEncryptor(encryption_key, {iv: iv}); 
var ciphertext = aesEncryptor.process(plaintext); 

message = sjcl.bitArray.concat(message, ciphertext);  

var hmac = new sjcl.misc.hmac(hmac_key).encrypt(message); 

var encrypted_data = sjcl.bitArray.concat(message, hmac); 
var output = sjcl.codec.hex.fromBits(encrypted_data); 

console.log(output); 

當我登錄的message輸出的第一套sjcl.bitArray.concat完成後,所有的返回是versioniv第一個串聯。最後的十六進制輸出只是第一個級聯和hmac級聯。這加強了我的懷疑,即它可能是CryptoJS的錯,因爲輸出串接工作並且在兩個sjcl變量之間。

我試過使用SJCL隨機位陣列,但有一些麻煩。使用

new sjcl.prng.randomWords(32/4); 

new sjcl.prng(32/4); 

而且sjcl.random.randomWords時似乎並沒有工作了SJCL的發電機,prng,沒有工作。

回答

2

CryptoJS(WordArray)和SJCL(bitArray)具有不同的數據內部表示。你不能簡單地連接它們。

最簡單的方法將是可能給它的另一側解碼編碼成作爲十六進制這樣的中間格式,讓進入其內部格式:

message = sjcl.bitArray.concat(version, sjcl.codec.hex.toBits(iv.toString())); 

WordArray#toString()自動使用十六進制編碼。你將不得不對所有行做到這一點,但是這是一個有點矯枉過正,因爲你可以連接十六進制字符串作爲字符串:

message = sjcl.codec.hex.toBits("03" + iv + encryption_salt + hmac_salt + iv); 

這應該按預期工作,因爲自動添加如ivWordArray爲一個字符串調用它的toString()函數,該函數又產生一個大端的十六進制編碼的字符串。

我想知道爲什麼你使用iv兩次。也許你的意思是options其中之一。


需要改變什麼:

function convert(wordArray){ 
    return sjcl.codec.hex.toBits(wordArray.toString()); 
} 
var message = "0301" + encryption_salt + hmac_salt + iv; 

var ciphertext = CryptoJS.AES.encrypt(plaintext, encryption_key, {iv: iv}).ciphertext; 

message += ciphertext; 
message = sjcl.codec.hex.toBits(message); 

var hmac = new sjcl.misc.hmac(convert(hmac_key)).encrypt(message); 

var encrypted_data = sjcl.bitArray.concat(message, hmac); 
var output = sjcl.codec.hex.fromBits(encrypted_data); 

console.log(output); 
+0

是啊,這應該是選項。忘了改變調試。感謝您的解決方案。這部分工作,但現在密文沒有被包括在內,'hmac'緊接在'iv'之後。感謝您的反饋! – PizzaPleb

+0

忘了向下滾動。其他功能也一樣。您需要轉換表示。 –

+0

試圖通過'message + ciphertext'和'message + hmac'將'toBits'串聯應用到各種字符串格式組合的結尾,但是這樣會持續出現帶有許多0的字符串。編碼不是我的包。感謝您的耐心等待。 – PizzaPleb