9

我对 NodeJs 很陌生,并试图弄清楚如何使用“加密”模块。在玩弄它时,我注意到 NodeJs 和 crypto-js 中的“crypto”模块之间的区别:

使用 crypto-js,我有:

function SHA256Hash(password, salt, iteration) {
    var saltedpassword = salt + password;
    var sha256 = CryptoJS.algo.SHA256.create();
    for(var i = 0; i < iteration; i++) {
            alert("saltedpassword = " + saltedpassword);
            sha256.update(saltedpassword);
            var saltedpassword = sha256.finalize();
            sha256.reset();
    }       
    return saltedpassword.toString(CryptoJS.enc.Base64);
}

然后调用:

var hashedPassword = SHA256Hash("123456789", "ASIN", 3)

并接收:

saltedpassword = ASIN123456789
saltedpassword = 3362d80b757d14bfe18c01f6a003ed38a3a4a3dcab0417efb457b71740e21411
saltedpassword = 6020c992a9b7cd3ca9e95b9a3e21b64911edb7983b3dd77bdcecda19f2756987

使用“加密”模块,我写道:

function SHA256Hash(password, salt, iteration) {
    var saltedpassword = salt + password;
    for(var i = 0; i < iteration-1; i++) { 
            console.log("saltedpassword = "+saltedpassword)
            var sha256 = crypto.createHash('sha256');
            sha256.update(saltedpassword);
            var saltedpassword = sha256.digest('hex');
    }       
    console.log("saltedpassword = "+saltedpassword)
    var sha256 = crypto.createHash('sha256');
    sha256.update(saltedpassword);
    return sha256.digest('base64');
}

然后调用:

var hashedPassword = SHA256Hash("123456789", "ASIN", 3);

并收到:

saltedpassword = ASIN123456789
saltedpassword = 3362d80b757d14bfe18c01f6a003ed38a3a4a3dcab0417efb457b71740e21411
saltedpassword = 4795d40ae8ae797f0ce51dfe4b496bca68f6d1f4a264f4ca52348ddd65a2988d

前两项相同,但第三项不同。我错过了什么吗?

已编辑:当我与 Jasypt 进行比较时,CryptoJs 会生成类似的密钥。我的问题是如何调整“加密”模块以使其生成与 CryptoJS 和 Jasypt 相同的密钥。

4

4 回答 4

3

显然我不能为怪胎的答案添加评论,所以我会在这里写:

重置()工作正常。显着的区别是您在迭代循环中将哈希输出转换为十六进制字符串。

于 2012-12-26T02:25:27.823 回答
1

请改用 PKDF2!

为什么不使用node-crypto的内置PBKDF2

var hashedpw = crypto.pbkdf2Sync(password, salt, iterations, keysize);

crypto-js

var hashedpw = CryptoJS.PBKDF2(
    password, 
    salt, 
    { keySize: keysize/32, iterations: iterations }
);

它不仅比您尝试做的更安全,因为它的计算成本比重复哈希要高得多,而且实现起来也容易得多。

于 2014-03-31T11:29:32.027 回答
1

在 cryptojs 示例中,finalize() 返回原始二进制数据。在加密模块示例中,digest() 返回一个十六进制字符串。当您迭代地重新散列时,输出的差异意味着输入的差异。

于 2012-12-26T01:20:39.853 回答
0

我做了一些测试,显然这个reset函数(在 crypto-js 中)搞砸了。我不确定它的作用,也没有足够的耐心来寻找问题。:) 但是,这是可行的解决方案:

function SHA256Encrypt(password, salt, iteration) {
    var saltedpassword = salt + password;
    for(var i = 0; i < iteration-1; i++) {
        alert("saltedpassword = " + saltedpassword);
        saltedpassword = CryptoJS.SHA256( saltedpassword ).toString( CryptoJS.enc.Hex );
    }
    saltedpassword = CryptoJS.SHA256( saltedpassword );
    return saltedpassword.toString(CryptoJS.enc.Base64);
}

这使得两个代码更加相似,这很好。

于 2012-12-13T11:35:01.893 回答