2

I'm using Crypto to hash a string with salt 200 times. I had a weird behavior where the hash would always be the same. I now have it returning what appears to be proper results, but I'm wondering if someone can tell me why.

This is the original code that yields the same hash every time (assuming the same salt):

const crypto = require('crypto');

console.log(hashPwd('abc', '11111111111111111111111111111111'));
console.log(hashPwd('def', '11111111111111111111111111111111'));


function hashPwd(password, hexSalt){
    var salt = hex2a(hexSalt);
    var hashPwd = crypto.createHash('sha256').update(salt + password);
    for(var x =0; x < 199; x++){
        hashPwd = crypto.createHash('sha256').update(salt + hashPwd);
    }
    return hashPwd.digest('hex');
}

//From: http://stackoverflow.com/questions/3745666/how-to-convert-from-hex-to-ascii-in-javascript
function hex2a(hexx) {
    var hex = hexx.toString();//force conversion
    var str = '';
    for (var i = 0; i < hex.length; i += 2)
        str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
    return str;
}

The above output yields:

52cfd2b127266c1c846ded37c986d8663506118332437daa6eadbc32525c2aa4
52cfd2b127266c1c846ded37c986d8663506118332437daa6eadbc32525c2aa4

While the following code returns the expected results:

const crypto = require('crypto');

console.log(hashPwd('abc', '11111111111111111111111111111111'));
console.log(hashPwd('def', '11111111111111111111111111111111'));

function hashPwd(password, hexSalt){
    const hasher = crypto.createHash('sha256');
    var salt = hex2a(hexSalt);
    var hashPwd = hasher.update(salt + password);
    for(var x =0; x < 199; x++){
        hashPwd = hasher.update(salt + hashPwd);
    }
    return hashPwd.digest('hex');
}

//From: http://stackoverflow.com/questions/3745666/how-to-convert-from-hex-to-ascii-in-javascript
function hex2a(hexx) {
    var hex = hexx.toString();//force conversion
    var str = '';
    for (var i = 0; i < hex.length; i += 2)
        str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
    return str;
}

Yields the proper:

05525f74c0220924a2c9626ca75c2d997bf8b49a8c74208501aaf7a222d11899
c846cb3dc58163530b7b7afc7b467c104fa11566f405b333d030e5e6595bfaec

Can someone please explain why?

Doug
  • 6,446
  • 9
  • 74
  • 107
  • On a semi-related note, you shouldn't use a plain hash for passwords if you're in control of everything. Instead, consider using something like bcrypt (or possibly scrypt or pbkdf2). – mscdex Apr 07 '17 at 02:48
  • @mscdex Thank-you for the suggestion. I actually started with bcrypt, but the first few libraries I used didn't play well on Windows. For this particular application 200 iterations of sha256 should really be way more than sufficient. I clearly need to fix my errors so this is done right though. – Doug Apr 07 '17 at 03:39

1 Answers1

3

You can see just by looking at the result of

crypto.createHash('sha256').update('abc')+'123'

> '[object Object]123'

When you try to add a string to your hash object, you are casting the hash to a string, which results in this constant string.

If you used

hashPwd = crypto.createHash('sha256').update(salt + hashPwd).digest('hex')

It would work properly.

So essentially you are just hashing the string salt+'[object Object]' over and over.

Tjaden Hess
  • 291
  • 2
  • 11
  • That makes perfect sense as to why the first code sample failed. However, if that is the case, why is the second code sample giving me what seems like good results? Shouldn't it do the same thing? – Doug Apr 07 '17 at 03:01
  • 1
    In the second one, the first update uses the actual password. After that you're just updating with the useless string. But that first hash will leave the internal states different – Tjaden Hess Apr 07 '17 at 03:04
  • @TjadenHess I'm using crypto to use create the hash. Works fine while registering but while in the signing function If I generate a hash with same salt and password I get a different value. d3e962cd26dc018145efcd88ec1d23486e10046314760a2e3d5b05283c66 d3e962cd26dc018145efcd88ec1d23486e10046314760a2e3d5b05283c66191e see the last 4 digit which is added song. I dunno what to do. to create hash I used the same code you provided above. Kidnly help me – Gopi P May 26 '20 at 12:23