Reputation: 111
I'm quite new to NodeJs and trying to figure out how to use the "crypto" module. While playing around with it I notice the difference between the "crypto" module in NodeJs and crypto-js:
With crypto-js, I have:
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);
}
Then call :
var hashedPassword = SHA256Hash("123456789", "ASIN", 3)
And receive :
saltedpassword = ASIN123456789
saltedpassword = 3362d80b757d14bfe18c01f6a003ed38a3a4a3dcab0417efb457b71740e21411
saltedpassword = 6020c992a9b7cd3ca9e95b9a3e21b64911edb7983b3dd77bdcecda19f2756987
With "crypto" module, I wrote:
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');
}
Then call:
var hashedPassword = SHA256Hash("123456789", "ASIN", 3);
And receive:
saltedpassword = ASIN123456789
saltedpassword = 3362d80b757d14bfe18c01f6a003ed38a3a4a3dcab0417efb457b71740e21411
saltedpassword = 4795d40ae8ae797f0ce51dfe4b496bca68f6d1f4a264f4ca52348ddd65a2988d
The first two items are the same but the third item is different. Did I miss out something ?
Edited: As I compare to the Jasypt, CryptoJs generates similar keys. My question is how to tune "crypto" module to make it generate the same keys as CryptoJS and Jasypt do.
Upvotes: 11
Views: 22522
Reputation: 25039
Why are you not using the built-in PBKDF2 from node-crypto:
var hashedpw = crypto.pbkdf2Sync(password, salt, iterations, keysize);
and crypto-js:
var hashedpw = CryptoJS.PBKDF2(
password,
salt,
{ keySize: keysize/32, iterations: iterations }
);
Not only is it more secure than what you're trying to do by being much more expensive to compute than repeated hashing, it's also a lot easier to implement.
Upvotes: 0
Reputation: 2583
Apparently I can't add comments to freakish's answer, so I'll write it here instead:
reset() works fine. The significant difference is you're converting the hash output to a hex string within the iteration loop.
Upvotes: 3
Reputation: 2583
In the cryptojs example, finalize() returns raw binary data. In the crypto module example, digest() is returning a hex string. That difference in output means a difference in input when you iteratively re-hash.
Upvotes: 1
Reputation: 56577
I've done some tests and apparently this reset
function ( in crypto-js ) messes up. I'm not sure what it does and I don't have enough patience to look for an issue. :) However, here's the working solution:
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);
}
which makes both codes even more similar, which is good.
Upvotes: 0