Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJS "crypto" hash seems to produce different output than Crypto-JS javascript library

I am using NodeJS's bundled crypto module for SHA256 hashing on the server-side. On the client-side, I am using a javascript library called Crypto-JS.

I am using SHA256 hashes for a login system that uses classical nonce-based authentication. However, my server-side and client-side hash-digests don't match up even when the hash-messages are the same (I have checked this). Even the length of the hash-digests are different.

This is a snippet of my client-side implementation:

var password_hash = CryptoJS.SHA256( token.nonce /*this is the server's nonce*/ + cnonce + password ).toString(CryptoJS.enc.Base64);

This is a snippet of my server-side implementation:

var sha256 = CRYPTO.createHash("sha256");
sha256.update(snonce+cnonce+password, "utf-8");
var hash = sha256.digest("base64");

This is some sample data:

client-digest: d30ab96e65d09543d7b97d7cad6b6cf65f852f5dd62c256595a7540c3597eec4
server-digest: vZaCi0mCDufqFUwVO40CtKIW7GS4h+XUhTUWxVhu0HQ=

client-message: O1xxQAi2Y7RVHCgXoX8+AmWlftjSfsrA/yFxMaGCi38ZPWbUZBhkVDc5eadCHszzbcOdgdEZ6be+AZBsWst+Zw==b3f23812448e7e8876e35a291d633861713321fe15b18c71f0d54abb899005c9princeofnigeria
server-message: O1xxQAi2Y7RVHCgXoX8+AmWlftjSfsrA/yFxMaGCi38ZPWbUZBhkVDc5eadCHszzbcOdgdEZ6be+AZBsWst+Zw==b3f23812448e7e8876e35a291d633861713321fe15b18c71f0d54abb899005c9princeofnigeria 

Does anyone know why the hashes are different? I thought that if it is the same protocol/algorithm, it will always produce the same hash.

Edit: Wow. I went to this online hashing tool and it produces yet another digest for the same message:

4509a6d5028b217585adf41e7d49f0e7c1629c59c29ce98ef7fbb96c6f27502c

Edit Edit: On second thought, the reason for the online hashing tool being different is probably because it uses a hex encoding and I used base64

like image 350
Joshua Avatar asked Sep 07 '25 11:09

Joshua


2 Answers

The problem was indeed with encodings.

Look at the client-side implementation:

var password_hash = CryptoJS.SHA256(message).toString(CryptoJS.enc.Base64);

The CryptoJS.enc.Base64 parameter actually requires another component in the CryptoJS library that I did not include (stored in a js file: enc-base64-min.js). So, in the absence of a valid encoding type, it defaulted to hex.

Thanks @dhj for pointing out the encoding issue!

like image 141
Joshua Avatar answered Sep 10 '25 08:09

Joshua


The problem is that your client produces hex-encoded digest, while server uses base64 encoding.

like image 22
Nickolay Olshevsky Avatar answered Sep 10 '25 07:09

Nickolay Olshevsky