【问题标题】:SJCL not concatenating bit arraysSJCL 不连接位数组
【发布时间】:2015-11-13 08:10:39
【问题描述】:

我正在尝试使用使用 SJCL 的 RNCryptor-JS,但由于某种原因,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.bitArray.concat 完成后记录message 的输出时,返回的只是versioniv 的第一个串联。最终的十六进制输出就是第一个连接和hmac 连接。这加强了我的怀疑,即这可能是 CryptoJS 的错,因为输出连接有效并且位于两个 sjcl 变量之间。

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

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

new sjcl.prng(32/4);

sjcl.random.randomWords 似乎不再起作用了。

【问题讨论】:

    标签: javascript cryptojs bitarray rncryptor sjcl


    【解决方案1】:

    CryptoJS (WordArray) 和 SJCL (bitArray) 具有不同的数据内部表示。您不能简单地将它们连接起来。

    最简单的方法可能是把它编码成一个中间格式,比如Hex,让对方解码成它的内部格式:

    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 两次。也许您的意思是其中一个上的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);
    

    【讨论】:

    • 是的,这应该是选项。忘记从调试中更改。感谢您的解决方案。这部分有效,但现在不包括密文,hmac 紧跟在iv 之后。感谢您的反馈!
    • 忘记向下滚动。这同样适用于其他功能。您需要转换表示形式。
    • 尝试将toBitsmessage + ciphertextmessage + hmac 连接到末尾,并使用各种字符串格式组合,但不断出现带有许多0 的字符串。编码不是我的包。感谢您的耐心等待。
    • 您需要跟踪message 当前所处的格式。+ 仅在它是字符串时才有意义,但如果它是像您的问题中的 bitArray 则不起作用.我在答案中添加了一个示例。
    • 更新:渐进式密码尚未最终确定。还能够使用message = sjcl.codec.hex.fromBits(message) + ciphertext.toString(CryptoJS.enc.Hex)sjcl.codec.hex.toBits(message) 连接所有内容。底部的message + hmac 不需要它。整个十六进制输出现已完成。只需要找出为什么 HMAC 不排队。再次感谢您的帮助!
    猜你喜欢
    • 2021-09-24
    • 1970-01-01
    • 2021-08-14
    • 2015-11-18
    • 1970-01-01
    • 1970-01-01
    • 2018-07-15
    相关资源
    最近更新 更多