nodejs crypto module vs crypto-js

13,913

Solution 1

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.

Solution 2

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.

Solution 3

Use PKDF2 instead!

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.

Share:
13,913
Mono
Author by

Mono

Updated on July 26, 2022

Comments

  • Mono
    Mono almost 2 years

    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.

  • Mono
    Mono over 11 years
    Thanks, freakish. That will make string encrypted by crypto-js identical to one created by crypto module. Do you have any idea how to make it the other way round ? One reason is when I compare these two with my Java snippet(using Jasypt 1.7). It turns out the crypto-js works similarly to the Jasypt.
  • Mono
    Mono over 11 years
    Thanks, Jeff. I've tried changing to digest('binary') within the loop and it throws the same result now. For the cryptojs, when I tried to print out the output of finalize(), it show 'hex' string. So I thought I should use digest('hex').