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?
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).