4

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

7
  • I get the same one as the online hashing tool. Are you sure you aren't changing the encoding of the string between the client and server? Maybe a serialization protocol or a change from ascii to utf or back? Just one bit different will give a completely different hash. Commented Dec 22, 2012 at 5:26
  • @dhj I don't think the encoding changed anything. I converted all my nonces to base64 so everything is a string. I also console logged the hash-message on both the browser and server and compared them (the hash-message in the question is copy pasted from console output). Commented Dec 22, 2012 at 5:29
  • 1
    Well that server and client digest are definitely two different result encodings. The client is in hex the server probably base64. SHA256 will always return a 256 bit digest. Commented Dec 22, 2012 at 5:40
  • @dhj Oh yeah! The client-digest looks very much like a hex string. This is perplexing...I explicitly told it to output a base64 string with .toString(CryptoJS.enc.Base64);...I'll have to think of a workaround... Commented Dec 22, 2012 at 5:46
  • @dhj Found the problem! Thank you! Commented Dec 22, 2012 at 5:56

2 Answers 2

5

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!

Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.