How can I get the sha1 hash of a string in node.js?

How can I get the sha1 hash of a string in node.js?

I’m trying to create a websocket server written in node.js
To get the server to work I need to get the SHA1 hash of a string.
What I have to do is explained in Section 5.2.2 page 35 of the docs.

NOTE: As an example, if the value of the “Sec-WebSocket-Key”
header in the client’s handshake were “dGhlIHNhbXBsZSBub25jZQ==”, the server would append thestring “258EAFA5-E914-47DA-95CA-C5AB0DC85B11” to form the
string “dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11”. The server would then take the SHA-1 hash of this string, giving the value 0xb3 0x7a 0x4f 0x2c 0xc0 0x62 0x4f 0x16 0x90 0xf6 0x46 0x06 0xcf 0x38 0x59 0x45 0xb2 0xbe 0xc4 0xea. This value is then base64-encoded, to give the value “s3pPLMBiTxaQ9kYGzzhZRbK+xOo=”, which would be returned
in the “Sec-WebSocket-Accept” header.

Solutions/Answers:

Solution 1:

See the crypto.createHash() function and the associated hash.update() and hash.digest() functions:

var crypto = require('crypto')
  , shasum = crypto.createHash('sha1');
shasum.update("foo");
console.log(shasum.digest('hex'));
// "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"

Solution 2:

Obligatory: SHA1 is broken, you can make collisions with the AWS credits of the average startup accelerator cohort but to answer your question:

var getSHA1ofJSON = function(input){
    return crypto.createHash('sha1').update(JSON.stringify(input)).digest('hex')
}

Then:

getSHA1ofJSON('whatever')

or

getSHA1ofJSON(['whatever'])

or

getSHA1ofJSON({'this':'too'})

Solution 3:

Please read and strongly consider my advice in the comments of your post. That being said, if you still have a good reason to do this, check out this listing of crpyto modules for Node. It has modules for dealing with both sha1 and base64.

Solution 4:

Tips to prevent issue (bad hash) :

I experienced that NodeJS is hashing the UTF-8 representation of the string. Other languages (like Python, PHP or PERL…) are hashing the byte string.

We can add binary argument to use the byte string.

const crypto = require("crypto");

function sha1(data) {
    return crypto.createHash("sha1").update(data, "binary").digest("hex");
}

sha1("Your text ;)");

You can try with : “\xac”, “\xd1”, “\xb9”, “\xe2”, “\xbb”, “\x93”, etc…

Other languages (Python, PHP, …):

sha1("\xac") //39527c59247a39d18ad48b9947ea738396a3bc47

Nodejs:

sha1 = crypto.createHash("sha1").update("\xac", "binary").digest("hex") //39527c59247a39d18ad48b9947ea738396a3bc47
//without:
sha1 = crypto.createHash("sha1").update("\xac").digest("hex") //f50eb35d94f1d75480496e54f4b4a472a9148752