I have benn going at this for a few hours now and can't seem to find a similar problem on here or anywhere else. After desperately looking for small typos or other errors I turn to you.
I am implementing encryption for the first time and so far all has been working out succesfully, I am using the crypto library together with Node.js to hash and salt the passwords. So far that has worked fine, but when I try to do the iterative rehashing I do not get the same key.
Let me show you my code:
from the app.get method:
var salt = crypto.randomBytes(128);
var hash = crypto.createHash('sha256');
hash.update(salt.toString('base64') + request.query.password);
var hashedKey = hash.digest('base64');
console.log("original pass is: " + hashedKey)
var stretchedKey = crypto.pbkdf2Sync(hashedKey, salt, 1000, 128);
var promise = db.User.create({
username: request.query.username.toLowerCase(),
email: request.query.email.toLowerCase(),
encryptedPassword: stretchedKey.toString('base64'),
randomSalt: salt.toString('base64'),
premium: true
});
as you can see in the above I generate a random salt for the new user, append the password to it and hash it. After that I try to stretch it and then save it in the database
Here is the code from the authentication method:
var hash = crypto.createHash('sha256');
hash.update(user.randomSalt.toString('base64') + request.query.password);
var hashedKey = hash.digest('base64');
console.log("redone pass is: " + hashedKey)
var stretchedKey = crypto.pbkdf2Sync(hashedKey, user.randomSalt, 1000, 128);
console.log("!! " + stretchedKey.toString('base64') + "\n!! " + user.encryptedPassword)
//protect against timing attacks
var check = 0;
for (var i = 0; i < stretchedKey.toString('base64').length; i++)
{
if (stretchedKey.toString('base64').charAt(i) !== user.encryptedPassword.charAt(i) )
{
check++;
}
}
if (check === 0)
{
response.json({
status: 'correct pass'
});
}
else
{
response.json({
status: 'wrong pass'
});
}
});
The two console.log that logs "hashedKey" shows the same result that is: 6lYiSRufti1MBxyMKQKTb5RBM3Ff9qZqzXasXSHPv0E=
The longer console log that logs the two rehashed passwords produce this:
ts1b7SpI9Wsemk05Sx/SEYs6mbQa9dbU0qbOxP5Z5oC27yeaBi5syaQDTRDuzWkqtGeUBSNhaoCfAyXN4O9eX8ar5IBEGoGx5T4nb8PFu89XuR3/ZfvF+mbwezzfReUW7BYzqOCugB8v+7hFCmpAvG5OZ9uoDGiKh/Uh0mRXOmI=
and this
l/2Rq3s3caek2NNQBJ9mRXBcztX0PTGy0bXksriqLX128NkPJ7j6UeeoKyRSh/Bxdfavb0V/C3LUzDSOLruQSA+Y29mEXIbhVjloVtJJGpN+ACckSlf447xlcVF29IlwJn1sN6GvRlYJuuxB8b9Q3Yz7DWaM1PcmN9+oRyeAD0E=
Can any of you tell me where I might be going wrong here?
Thanks in advance Peter
The reason for your mismatch in results is due to inconsistent Base64'ing of your salt.
If you instead of:
var stretchedKey = crypto.pbkdf2Sync(hashedKey, salt, 1000, 128);
you should use:
var stretchedKey = crypto.pbkdf2Sync(hashedKey, salt.toString('base64'), 1000, 128);
Best regards