I have a string that I want to hash. What's the easiest way to generate the hash in node.js?
The hash is for versioning, not security.
If you just want to md5 hash a simple string I found this works for me.
var crypto = require('crypto');
var name = 'braitsch';
var hash = crypto.createHash('md5').update(name).digest('hex');
console.log(hash); // 9b74c9897bac770ffc029102a200c5de
Take a look at crypto.createHash(algorithm)
var filename = process.argv[2];
var crypto = require('crypto');
var fs = require('fs');
var md5sum = crypto.createHash('md5');
var s = fs.ReadStream(filename);
s.on('data', function(d) {
md5sum.update(d);
});
s.on('end', function() {
var d = md5sum.digest('hex');
console.log(d + ' ' + filename);
});
Node's crypto module API is still unstable.
As of version 4.0.0, the native Crypto module is not unstable anymore. From the official documentation:
Crypto Stability: 2 - Stable The API has proven satisfactory. Compatibility with the npm ecosystem is a high priority, and will not be broken unless absolutely necessary.
So, it should be considered safe to use the native implementation, without external dependencies.
For reference, the modules mentioned bellow were suggested as alternative solutions when the Crypto module was still unstable.
You could also use one of the modules sha1 or md5 which both do the job.
$ npm install sha1
and then
var sha1 = require('sha1');
var hash = sha1("my message");
console.log(hash); // 104ab42f1193c336aa2cf08a2c946d5c6fd0fcdb
or
$ npm install md5
and then
var md5 = require('md5');
var hash = md5("my message");
console.log(hash); // 8ba6c19dc1def5702ff5acbf2aeea5aa
(MD5 is insecure but often used by services like Gravatar.)
The API of these modules won't change!
crypto
module built into the platform. Another advantage is that you can use my module on the server as well as the client side. But it is totally up to you, what library you use.
sha256("string or binary");
I experienced issue with other answer. I advice you to set encoding argument to binary
to use the byte string and prevent different hash between Javascript (NodeJS) and other langage/service like Python, PHP, Github...
If you don't use this code, you can get a different hash between NodeJS and Python...
How to get the same hash that Python, PHP, Perl, Github (and prevent an issue) :
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.
Code :
const crypto = require("crypto");
function sha256(data) {
return crypto.createHash("sha256").update(data, "binary").digest("base64");
// ------ binary: hash the byte string
}
sha256("string or binary");
Documentation:
crypto.createHash(algorithm[, options]): The algorithm is dependent on the available algorithms supported by the version of OpenSSL on the platform.
hash.digest([encoding]): The encoding can be 'hex', 'latin1' or 'base64'. (base 64 is less longer).
You can get the issue with : sha256("\xac"), "\xd1", "\xb9", "\xe2", "\xbb", "\x93", etc...
Other languages (like PHP, Python, Perl...) and my solution with .update(data, "binary") : sha1("\xac") //39527c59247a39d18ad48b9947ea738396a3bc47
Nodejs by default (without binary) : sha1("\xac") //f50eb35d94f1d75480496e54f4b4a472a9148752
Simple One Liners:
If you want UTF8 text hash:
const hash = require('crypto').createHash('sha256').update('Hash me', 'utf8').digest('hex');
If you want to get the same hash with Python, PHP, Perl, Github:
const hash = require('crypto').createHash('sha256').update('Hash me', 'binary').digest('hex');
You can also replace 'sha256'
with 'sha1'
, 'md5'
, 'sha256'
, 'sha512'
The crypto
module makes this very easy.
Setup:
// import crypto from 'crypto';
const crypto = require('crypto');
const sha256 = x => crypto.createHash('sha256').update(x, 'utf8').digest('hex');
Usage:
sha256('Hello, world. ');
Here you can benchmark all supported hashes on your hardware, supported by your version of node.js. Some are cryptographic, and some is just for a checksum. Its calculating "Hello World" 1 million times for each algorithm. It may take around 1-15 seconds for each algorithm (Tested on the Standard Google Computing Engine with Node.js 4.2.2).
for(var i1=0;i1<crypto.getHashes().length;i1++){
var Algh=crypto.getHashes()[i1];
console.time(Algh);
for(var i2=0;i2<1000000;i2++){
crypto.createHash(Algh).update("Hello World").digest("hex");
}
console.timeEnd(Algh);
}
Result: DSA: 1992ms DSA-SHA: 1960ms DSA-SHA1: 2062ms DSA-SHA1-old: 2124ms RSA-MD4: 1893ms RSA-MD5: 1982ms RSA-MDC2: 2797ms RSA-RIPEMD160: 2101ms RSA-SHA: 1948ms RSA-SHA1: 1908ms RSA-SHA1-2: 2042ms RSA-SHA224: 2176ms RSA-SHA256: 2158ms RSA-SHA384: 2290ms RSA-SHA512: 2357ms dsaEncryption: 1936ms dsaWithSHA: 1910ms dsaWithSHA1: 1926ms dss1: 1928ms ecdsa-with-SHA1: 1880ms md4: 1833ms md4WithRSAEncryption: 1925ms md5: 1863ms md5WithRSAEncryption: 1923ms mdc2: 2729ms mdc2WithRSA: 2890ms ripemd: 2101ms ripemd160: 2153ms ripemd160WithRSA: 2210ms rmd160: 2146ms sha: 1929ms sha1: 1880ms sha1WithRSAEncryption: 1957ms sha224: 2121ms sha224WithRSAEncryption: 2290ms sha256: 2134ms sha256WithRSAEncryption: 2190ms sha384: 2181ms sha384WithRSAEncryption: 2343ms sha512: 2371ms sha512WithRSAEncryption: 2434ms shaWithRSAEncryption: 1966ms ssl2-md5: 1853ms ssl3-md5: 1868ms ssl3-sha1: 1971ms whirlpool: 2578ms
RSA-
prefixes do?
I had to throw my 2 cents in hope this helps someone out.
For those using CommonJS
const crypto = require('crypto');
const secret = 'I love writing code, fixing things and building helpful tools';
const hash = crypto.createHmac('sha256', secret).digest('hex');
console.log('Hash successfully generated: ', hash);
For those using ES Modules
const { createHmac } = await import('crypto');
const secret = 'I love writing code, fixing things and building helpful tools';
const hash = createHmac('sha256', secret).digest('hex');
console.log('Hash successfully generated: ', hash);
Super simple! Happy Coding :)
Considering the thoughts from http://www.thoughtcrime.org/blog/the-cryptographic-doom-principle/ (in short: FIRST encrypt, THEN authenticate. Afterwards FIRST verify, THEN decrypt) I have implemented the following solution in node.js:
function encrypt(text,password){
var cipher = crypto.createCipher(algorithm,password)
var crypted = cipher.update(text,'utf8','hex')
crypted += cipher.final('hex');
return crypted;
}
function decrypt(text,password){
var decipher = crypto.createDecipher(algorithm,password)
var dec = decipher.update(text,'hex','utf8')
dec += decipher.final('utf8');
return dec;
}
function hashText(text){
var hash = crypto.createHash('md5').update(text).digest("hex");
//console.log(hash);
return hash;
}
function encryptThenAuthenticate(plainText,pw)
{
var encryptedText = encrypt(plainText,pw);
var hash = hashText(encryptedText);
return encryptedText+"$"+hash;
}
function VerifyThenDecrypt(encryptedAndAuthenticatedText,pw)
{
var encryptedAndHashArray = encryptedAndAuthenticatedText.split("$");
var encrypted = encryptedAndHashArray[0];
var hash = encryptedAndHashArray[1];
var hash2Compare = hashText(encrypted);
if (hash === hash2Compare)
{
return decrypt(encrypted,pw);
}
}
It can be tested with:
var doom = encryptThenAuthenticate("The encrypted text",user.cryptoPassword);
console.log(VerifyThenDecrypt(doom,user.cryptoPassword));
Hope this helps :-)
I use blueimp-md5 which is "Compatible with server-side environments like Node.js, module loaders like RequireJS, Browserify or webpack and all web browsers."
Use it like this:
var md5 = require("blueimp-md5");
var myHashedString = createHash('GreensterRox');
createHash(myString){
return md5(myString);
}
If passing hashed values around in the open it's always a good idea to salt them so that it is harder for people to recreate them:
createHash(myString){
var salt = 'HnasBzbxH9';
return md5(myString+salt);
}
function md5(a) {
var r = 0,
c = "";
return h(a);
function h(t) {
return u(l(m(t)))
}
function l(t) {
return p(g(f(t), 8 * t.length))
}
function u(t) {
for (var e, i = r ? "0123456789ABCDEF" : "0123456789abcdef", n = "", o = 0; o < t.length; o++)
e = t.charCodeAt(o),
n += i.charAt(e >>> 4 & 15) + i.charAt(15 & e);
return n
}
function m(t) {
for (var e, i, n = "", o = -1; ++o < t.length;)
e = t.charCodeAt(o),
i = o + 1 < t.length ? t.charCodeAt(o + 1) : 0,
55296 <= e && e <= 56319 && 56320 <= i && i <= 57343 && (e = 65536 + ((1023 & e) << 10) + (1023 & i),
o++),
e <= 127 ? n += String.fromCharCode(e) : e <= 2047 ? n += String.fromCharCode(192 | e >>> 6 & 31, 128 | 63 & e) : e <= 65535 ? n += String.fromCharCode(224 | e >>> 12 & 15, 128 | e >>> 6 & 63, 128 | 63 & e) : e <= 2097151 && (n += String.fromCharCode(240 | e >>> 18 & 7, 128 | e >>> 12 & 63, 128 | e >>> 6 & 63, 128 | 63 & e));
return n
}
function f(t) {
for (var e = Array(t.length >> 2), i = 0; i < e.length; i++)
e[i] = 0;
for (i = 0; i < 8 * t.length; i += 8)
e[i >> 5] |= (255 & t.charCodeAt(i / 8)) << i % 32;
return e
}
function p(t) {
for (var e = "", i = 0; i < 32 * t.length; i += 8)
e += String.fromCharCode(t[i >> 5] >>> i % 32 & 255);
return e
}
function g(t, e) {
t[e >> 5] |= 128 << e % 32,
t[14 + (e + 64 >>> 9 << 4)] = e;
for (var i = 1732584193, n = -271733879, o = -1732584194, s = 271733878, a = 0; a < t.length; a += 16) {
var r = i,
c = n,
h = o,
l = s;
n = E(n = E(n = E(n = E(n = N(n = N(n = N(n = N(n = C(n = C(n = C(n = C(n = S(n = S(n = S(n = S(n, o = S(o, s = S(s, i = S(i, n, o, s, t[a + 0], 7, -680876936), n, o, t[a + 1], 12, -389564586), i, n, t[a + 2], 17, 606105819), s, i, t[a + 3], 22, -1044525330), o = S(o, s = S(s, i = S(i, n, o, s, t[a + 4], 7, -176418897), n, o, t[a + 5], 12, 1200080426), i, n, t[a + 6], 17, -1473231341), s, i, t[a + 7], 22, -45705983), o = S(o, s = S(s, i = S(i, n, o, s, t[a + 8], 7, 1770035416), n, o, t[a + 9], 12, -1958414417), i, n, t[a + 10], 17, -42063), s, i, t[a + 11], 22, -1990404162), o = S(o, s = S(s, i = S(i, n, o, s, t[a + 12], 7, 1804603682), n, o, t[a + 13], 12, -40341101), i, n, t[a + 14], 17, -1502002290), s, i, t[a + 15], 22, 1236535329), o = C(o, s = C(s, i = C(i, n, o, s, t[a + 1], 5, -165796510), n, o, t[a + 6], 9, -1069501632), i, n, t[a + 11], 14, 643717713), s, i, t[a + 0], 20, -373897302), o = C(o, s = C(s, i = C(i, n, o, s, t[a + 5], 5, -701558691), n, o, t[a + 10], 9, 38016083), i, n, t[a + 15], 14, -660478335), s, i, t[a + 4], 20, -405537848), o = C(o, s = C(s, i = C(i, n, o, s, t[a + 9], 5, 568446438), n, o, t[a + 14], 9, -1019803690), i, n, t[a + 3], 14, -187363961), s, i, t[a + 8], 20, 1163531501), o = C(o, s = C(s, i = C(i, n, o, s, t[a + 13], 5, -1444681467), n, o, t[a + 2], 9, -51403784), i, n, t[a + 7], 14, 1735328473), s, i, t[a + 12], 20, -1926607734), o = N(o, s = N(s, i = N(i, n, o, s, t[a + 5], 4, -378558), n, o, t[a + 8], 11, -2022574463), i, n, t[a + 11], 16, 1839030562), s, i, t[a + 14], 23, -35309556), o = N(o, s = N(s, i = N(i, n, o, s, t[a + 1], 4, -1530992060), n, o, t[a + 4], 11, 1272893353), i, n, t[a + 7], 16, -155497632), s, i, t[a + 10], 23, -1094730640), o = N(o, s = N(s, i = N(i, n, o, s, t[a + 13], 4, 681279174), n, o, t[a + 0], 11, -358537222), i, n, t[a + 3], 16, -722521979), s, i, t[a + 6], 23, 76029189), o = N(o, s = N(s, i = N(i, n, o, s, t[a + 9], 4, -640364487), n, o, t[a + 12], 11, -421815835), i, n, t[a + 15], 16, 530742520), s, i, t[a + 2], 23, -995338651), o = E(o, s = E(s, i = E(i, n, o, s, t[a + 0], 6, -198630844), n, o, t[a + 7], 10, 1126891415), i, n, t[a + 14], 15, -1416354905), s, i, t[a + 5], 21, -57434055), o = E(o, s = E(s, i = E(i, n, o, s, t[a + 12], 6, 1700485571), n, o, t[a + 3], 10, -1894986606), i, n, t[a + 10], 15, -1051523), s, i, t[a + 1], 21, -2054922799), o = E(o, s = E(s, i = E(i, n, o, s, t[a + 8], 6, 1873313359), n, o, t[a + 15], 10, -30611744), i, n, t[a + 6], 15, -1560198380), s, i, t[a + 13], 21, 1309151649), o = E(o, s = E(s, i = E(i, n, o, s, t[a + 4], 6, -145523070), n, o, t[a + 11], 10, -1120210379), i, n, t[a + 2], 15, 718787259), s, i, t[a + 9], 21, -343485551),
i = v(i, r),
n = v(n, c),
o = v(o, h),
s = v(s, l)
}
return [i, n, o, s]
}
function _(t, e, i, n, o, s) {
return v((a = v(v(e, t), v(n, s))) << (r = o) | a >>> 32 - r, i);
var a, r
}
function S(t, e, i, n, o, s, a) {
return _(e & i | ~e & n, t, e, o, s, a)
}
function C(t, e, i, n, o, s, a) {
return _(e & n | i & ~n, t, e, o, s, a)
}
function N(t, e, i, n, o, s, a) {
return _(e ^ i ^ n, t, e, o, s, a)
}
function E(t, e, i, n, o, s, a) {
return _(i ^ (e | ~n), t, e, o, s, a)
}
function v(t, e) {
var i = (65535 & t) + (65535 & e);
return (t >> 16) + (e >> 16) + (i >> 16) << 16 | 65535 & i
}
}
string = 'hello';
console.log(md5(string));
Even if the hash is not for security, you can use sha instead of md5. In my opinion, the people should forget about md5 for now, it's in the past!
The normal nodejs sha256 is deprecated. So, you have two alternatives for now:
var shajs = require('sha.js') - https://www.npmjs.com/package/sha.js (used by Browserify)
var hash = require('hash.js') - https://github.com/indutny/hash.js
I prefer using shajs
instead of hash
, because I consider sha the best hash function nowadays and you don't need a different hash function for now. So to get some hash in hex you should do something like the following:
sha256.update('hello').digest('hex')
you can use crypto-js javaScript library of crypto standards, there is easiest way to generate sha256
or sha512
const SHA256 = require("crypto-js/sha256");
const SHA512 = require("crypto-js/sha512");
let password = "hello"
let hash_256 = SHA256 (password).toString();
let hash_512 = SHA512 (password).toString();
Success story sharing
require('crypto').createHash('md5').update(STRING_TO_BE_HASHED).digest("hex")
you got a one-liner. Cheers mate!.update
multiple times (github.com/joyent/node/issues/749) when trying to usetimbooo
's solution, using the one-liner fixed it (because the hash object is recreated every time).