Question

I'm switching my node.js's application's hashing algorythms from the JS based CryptoJS implementation to the node's own crypto implementation.

Here is my implementation:

var password = "password1";
var salt = generateSalt();
var iterations = 4000;
var keySize = 768/32;
var cryptoJSKey = CryptoJS.PBKDF2(password, salt, { "iterations": iterations , "keySize": keySize });
// base64 encoded key
cryptoJSKey = cryptoJSKey.toString(CryptoJS.enc.Base64);

require("crypto").pbkdf2( password, salt, iterations, keySize, function(err, derivedKey){
    var nodeCryptoKey = new Buffer( derivedKey, "binary" ).toString( "base64" );

    console.log( cryptoJSKey == nodeCryptoKey ); // always false!
});

One thing I noticed is that nodeCryptoKey ends up being 32 characters long and the cryptoJSKey is 192. If I increase the keySize for only node's crypto version to 144 (keySize * 6) the key ends up being 192 characters long as well - though it is still different.

Am I doing something wrong or do the implementations just differ from one another?

Was it helpful?

Solution

Looks like I figured it out.

In the rolled up PBKDF2.js script in "CryptoJS v3.0.2.zip" (the currently download) CryptoJS.enc.Base64 is undefined; this was probably intended, but not something I noticed.

I was comparing node's Base64 encoded output to CryptoJS's hex output.

Another caveat was that the keySizes aren't compatible between CryptoJS and node.js. Node needs keySize * 4 in order to output an identical key. I'm not familiar with what's going on under the hood in either case; but I'll just assume that's intended.

Node.js's PBKDF2's documentation is pretty scarce; it does, however, say its "key" parameter is named keylen, which is in bytes (or is it bits? I'm not sure).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top