chaîne de hachage node.js?


325

J'ai une chaîne que je veux hacher. Quelle est la façon la plus simple de générer le hachage dans node.js?

Le hachage est destiné au contrôle de version, pas à la sécurité.


Réponses:


224

Jetez un œil à crypto.createHash (algorithme)

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);
});

Que fait la fonction s.on ()? S'agit-il d'enregistrer la fonction md5sum.update (d) pour l'exécuter à chaque fois que des données sont lues à partir du ReadStream?
DucRP

@YoniDor Avez-vous essayé fs.readsync ? - Digérer dans une boucle while classique, puis assurez-vous que c'est fait ... ➝ stackoverflow.com/a/21219407/444255
Frank Nocke

8
OP veut hacher une chaîne, pas un fichier.
blimpse

699

Si vous voulez juste hacher md5 une chaîne simple, j'ai trouvé que cela fonctionne pour moi.

var crypto = require('crypto');
var name = 'braitsch';
var hash = crypto.createHash('md5').update(name).digest('hex');
console.log(hash); // 9b74c9897bac770ffc029102a200c5de

181
Woot woot, si vous l' require('crypto').createHash('md5').update(STRING_TO_BE_HASHED).digest("hex")avez , vous avez une doublure. Vive mec!
balupton

3
J'obtenais des problèmes en utilisant .updateplusieurs fois ( github.com/joyent/node/issues/749 ) lorsque j'essayais d'utiliser timbooola solution de, en utilisant le one-liner corrigé (car l'objet de hachage est recréé à chaque fois).
Max

Une façon de changer la longueur de la chaîne? Pas seulement 32 caractères, 64 ou 128 ou un nombre différent.
Mikel

@Mikel essayez s'il existe d'autres algorithmes de hachage qui répondent à vos besoins, md5 est toujours de 32 caractères.
Lie le

Si j'ai beaucoup de chaînes à hacher, il est moins efficace de continuer à appeler crypto.createHash au lieu de réutiliser le résultat?
Michael

81

L'API du module de chiffrement de Node est toujours instable.

Depuis la version 4.0.0, le module Crypto natif n'est plus instable. De la documentation officielle :

Crypto

Stabilité: 2 - Stable

L'API s'est avérée satisfaisante. La compatibilité avec l'écosystème npm est une priorité élevée et ne sera rompue qu'en cas d'absolue nécessité.

Ainsi, il devrait être considéré comme sûr d'utiliser l'implémentation native, sans dépendances externes.

Pour référence, les modules mentionnés ci-dessous ont été suggérés comme solutions alternatives lorsque le module Crypto était encore instable.


Vous pouvez également utiliser l'un des modules sha1 ou md5 qui font tous deux le travail.

$ npm install sha1

puis

var sha1 = require('sha1');

var hash = sha1("my message");

console.log(hash); // 104ab42f1193c336aa2cf08a2c946d5c6fd0fcdb

ou

$ npm install md5

puis

var md5 = require('md5');

var hash = md5("my message");

console.log(hash); // 8ba6c19dc1def5702ff5acbf2aeea5aa

(MD5 n'est pas sécurisé mais est souvent utilisé par des services comme Gravatar.)

L'API de ces modules ne changera pas!


9
Je pense qu'il est beaucoup plus facile et efficace d'utiliser Crypto plutôt que d'apporter un tout nouveau module.
Valjas

6
D'après les documents Node.js actuels: "Stabilité: 2 - Instable; les modifications de l'API sont en cours de discussion pour les versions futures. Les changements de rupture seront minimisés." L'API de mon module ne changera pas. Lorsque j'ai initialement écrit le module, aucun crypto module n'était intégré à la plateforme. Un autre avantage est que vous pouvez utiliser mon module sur le serveur ainsi que sur le côté client. Mais c'est à vous de décider quelle bibliothèque vous utilisez.
pvorb

7
La construction dans les hachages Crypto me donnait toujours le BS «La mise à jour du hachage a échoué». Enfin, je suis passé au module MD5 et cela a très bien fonctionné. Aussi plus facile à appeler (légèrement). Je vous remercie.
GJK

2
+1 pour une option qui reste à l'écart de la (2) - Nature instable de l'API Crypto!
Geek Stocks

1
J'ai résolu un problème étrange de sha1 sur le nœud 0.11.x sur ma machine Windows en échangeant l'utilisation de crypto standard pour ce module.
Bartvds

24
sha256("string or binary");

J'ai rencontré un problème avec une autre réponse. Je vous conseille de définir l'argument d'encodage binarypour utiliser la chaîne d'octets et empêcher un hachage différent entre Javascript (NodeJS) et d'autres langages / services comme Python, PHP, Github ...

Si vous n'utilisez pas ce code, vous pouvez obtenir un hachage différent entre NodeJS et Python ...

Comment obtenir le même hachage que Python, PHP, Perl, Github (et éviter un problème):

NodeJS hache la représentation UTF-8 de la chaîne. D'autres langages (comme Python, PHP ou PERL ...) hachent la chaîne d'octets.

Nous pouvons ajouter un argument binaire pour utiliser la chaîne d'octets.

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 (algorithme [, options]): L'algorithme dépend des algorithmes disponibles pris en charge par la version d'OpenSSL sur la plate-forme.
  • hash.digest ([encoding]): L'encodage peut être 'hex', 'latin1' ou 'base64'. (la base 64 est moins longue).

Vous pouvez obtenir le problème avec: sha256 ("\ xac"), "\ xd1", "\ xb9", "\ xe2", "\ xbb", "\ x93", etc ...

  • Autres langages (comme PHP, Python, Perl ...) et ma solution avec .update(data, "binary"):

      sha1("\xac") //39527c59247a39d18ad48b9947ea738396a3bc47
  • Nodejs par défaut (sans binaire):

      sha1("\xac") //f50eb35d94f1d75480496e54f4b4a472a9148752

15

Le cryptomodule rend cela très simple.

Installer:

// import crypto from 'crypto';
const crypto = require('crypto');

const sha256 = x => crypto.createHash('sha256').update(x, 'utf8').digest('hex');

Usage:

sha256('Hello, world. ');

10

Ici, vous pouvez comparer tous les hachages pris en charge sur votre matériel, pris en charge par votre version de node.js. Certains sont cryptographiques, et certains sont juste pour une somme de contrôle. Son calcul "Hello World" 1 million de fois pour chaque algorithme. Cela peut prendre environ 1 à 15 secondes pour chaque algorithme (testé sur le moteur de calcul Google standard avec 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);  
}

Résultat:
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
tourbillon: 2578ms


1
Que font les RSA-préfixes?
balupton

7

Doublures simples:

Si vous voulez un hachage de texte UTF8:

const hash = require('crypto').createHash('sha256').update('Hash me', 'utf8').digest('hex');

Si vous voulez obtenir le même hachage avec Python, PHP, Perl, Github:

const hash = require('crypto').createHash('sha256').update('Hash me', 'binary').digest('hex');

Vous pouvez également remplacer 'sha256'avec 'sha1', 'md5', 'sha256','sha512'


1

Compte tenu des réflexions de http://www.thoughtcrime.org/blog/the-cryptographic-doom-principle/ (en bref: FIRST encrypt, THEN authenticate. Ensuite FIRST verify, THEN decrypt), j'ai mis en œuvre la solution suivante dans le nœud. 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); 
    }
}

Il peut être testé avec:

var doom = encryptThenAuthenticate("The encrypted text",user.cryptoPassword);
console.log(VerifyThenDecrypt(doom,user.cryptoPassword));

J'espère que cela t'aides :-)


1

J'utilise blueimp-md5 qui est "compatible avec les environnements côté serveur comme Node.js, les chargeurs de modules comme RequireJS, Browserify ou webpack et tous les navigateurs Web."

Utilisez-le comme ceci:

var md5 = require("blueimp-md5");

var myHashedString = createHash('GreensterRox');

createHash(myString){
    return md5(myString);
}

Si passer des valeurs hachées à découvert, c'est toujours une bonne idée de les saler afin qu'il soit plus difficile pour les gens de les recréer:

createHash(myString){
    var salt = 'HnasBzbxH9';
    return md5(myString+salt);
}

1
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));

-1

Même si le hachage n'est pas pour la sécurité, vous pouvez utiliser sha au lieu de md5. À mon avis, les gens devraient oublier md5 pour l'instant, c'est du passé!

Le nodejs sha256 normal est obsolète. Donc, vous avez deux alternatives pour l'instant:

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

Je préfère utiliser shajsplutôt que hash, car je considère sha comme la meilleure fonction de hachage de nos jours et vous n'avez pas besoin d'une fonction de hachage différente pour l'instant. Donc, pour obtenir du hachage en hexadécimal, vous devriez faire quelque chose comme ceci:

sha256.update('hello').digest('hex')
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.