Javascript SJCL不连接位数组

Javascript SJCL不连接位数组,javascript,cryptojs,bitarray,rncryptor,sjcl,Javascript,Cryptojs,Bitarray,Rncryptor,Sjcl,我试图使用RNCryptor JS,它使用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

我试图使用RNCryptor JS,它使用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);
在完成第一组
sjcl.bitary.concat
之后,当我记录
消息的输出时,返回的只是
版本
iv
的第一次串联。最后的十六进制输出就是第一次级联和
hmac
级联。这加强了我的怀疑,即这可能是CryptoJS的错误,因为输出串联工作并且在两个sjcl变量之间

我尝试使用SJCL随机位数组,但遇到了一些问题。SJCL的生成器,
prng
,在使用时不工作

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

sjcl.random.randomWords
似乎不再工作。

CryptoJS()和sjcl()具有不同的数据内部表示形式。不能简单地将它们连接起来

最简单的方法可能是将其编码为中间格式,如十六进制,并让另一方解码为其内部格式:

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);
这应该按预期工作,因为向字符串添加
WordArray
,如
iv
,会自动调用其
toString()
函数,该函数会生成一个大端十六进制编码字符串

我想知道你为什么要用
iv
两次。也许你指的是其中一个上的
选项


需要改变的是:

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);

是的,那应该是选择。忘记从调试中更改。谢谢你的解决方案。这一部分是有效的,但现在密文不包括在内,
hmac
紧跟在
iv
之后。谢谢你的反馈!忘记向下滚动了。这同样适用于其他功能。您需要转换表示形式。尝试将
toBits
message+ciphertext
message+hmac
连接到末尾,并使用各种字符串格式组合,但始终会出现多个0的字符串。这不是我的包。感谢您的耐心等待。您需要跟踪当前使用的是哪种格式的
消息<代码>+
仅当它是字符串时才有意义,但如果它是像您问题中那样的位数组,则不起作用。我在回答中添加了一个示例。更新:渐进式密码尚未最终确定。还能够使用
message=sjcl.codec.hex.fromBits(message)+ciphertext.toString(CryptoJS.enc.hex)
sjcl.codec.hex.toBits(message)
连接所有内容。底部的
消息+hmac
不需要它。整个十六进制输出现在完成。只需要找出HMAC不排队的原因。再次感谢您的帮助!
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);