хеш-рядок node.js?


Відповіді:


224

Погляньте на crypto.createHash (алгоритм)

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

Що робить функція s.on ()? Чи це реєстрація функції md5sum.update (d) для виконання кожного разу, коли дані зчитуються з ReadStream?
DucRP

@YoniDor Ви спробували fs.readsync ? - Дайджест у класичному циклі, а тоді будьте впевнені, що це зроблено ... ➝ stackoverflow.com/a/21219407/444255
Френк Нокк

8
OP хоче хеш-рядок, а не файл.
блим

698

Якщо ви просто хочете, щоб md5 хеш простий рядок, я знайшов, це працює для мене.

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

181
Вуто вуо, якщо у require('crypto').createHash('md5').update(STRING_TO_BE_HASHED).digest("hex")вас є однолінійний . Будьмо, друже!
balupton

3
Отримував деякі проблеми, використовуючи .updateкілька разів ( github.com/joyent/node/isissue/749 ) при спробі використання timboooрішення, використовуючи однолінійну фіксовану версію (тому що хеш-об’єкт відтворюється кожен раз).
Макс

Будь-який спосіб змінити довжину рядка? Не тільки 32 символи, 64 або 128 або інше число.
Мікель

@Mikel спробуйте, якщо є інші хеш-алгоритми, які відповідають вашим потребам, md5 - це завжди 32 символи.
Зв'язки

Якщо у мене є багато рядків до хешу, менш ефективно продовжувати дзвінки crypto.createHash, а не якось повторно використовувати результат?
Майкл

81

API крипто-модуля Node все ще нестабільний.

З версії 4.0.0, рідний модуль Crypto вже не є нестабільним. З офіційної документації :

Криптовалюта

Стабільність: 2 - стабільна

API виявився задовільним. Сумісність з екосистемою npm є найважливішим пріоритетом, і вона не буде порушена, якщо немає абсолютно необхідності.

Отже, слід вважати безпечним використання нативного втілення, без зовнішніх залежностей.

Для довідки, згадані нижче модулі були запропоновані як альтернативні рішення, коли модуль Crypto був ще нестабільним.


Ви також можете використовувати один з модулів sha1 або md5, які обидва виконують цю роботу.

$ npm install sha1

і потім

var sha1 = require('sha1');

var hash = sha1("my message");

console.log(hash); // 104ab42f1193c336aa2cf08a2c946d5c6fd0fcdb

або

$ npm install md5

і потім

var md5 = require('md5');

var hash = md5("my message");

console.log(hash); // 8ba6c19dc1def5702ff5acbf2aeea5aa

(MD5 небезпечний, але часто використовується такими послугами, як Gravatar.)

API цих модулів не зміниться!


9
Я думаю, що використовувати Crypto набагато простіше та ефективніше, ніж залучати новий модуль.
Валяс

6
З поточних документів Node.js: "Стабільність: 2 - Нестабільна; зміни API обговорюються для майбутніх версій. Порушення змін буде мінімізовано." API мого модуля не зміниться. Коли я спочатку написав модуль, не було НЕ crypto модуль , вбудований в платформу. Ще одна перевага полягає в тому, що ви можете використовувати мій модуль як на сервері, так і на стороні клієнта. Але саме від вас залежить, якою бібліотекою ви користуєтесь.
pvorb

7
Збірка в крипто хешах продовжувала давати мені BS 'хеш-оновлення не вдалося'. Нарешті я перейшов до модуля MD5, і він працював просто чудово. Також простіше дзвонити (трохи). Дякую.
GJK

2
+1 для опції, що тримається подалі від (2) - Нестабільний характер Crypto API!
Geek Stocks

1
Я вирішив дивну проблему sha1 на вузлі 0.11.x на своїй машині Windows, замінивши стандартне використання криптовалют для цього модуля.
Bartvds

24
sha256("string or binary");

У мене виникло питання з іншою відповіддю. Раджу вам встановити аргумент кодування наbinary щоб використовувати рядок байтів і запобігати різному хешу між Javascript (NodeJS) та іншими ланцюгами / сервісами, такими як Python, PHP, Github ...

Якщо ви не використовуєте цей код, ви можете отримати інший хеш між NodeJS та Python ...

Як отримати той самий хеш, що і Python, PHP, Perl, Github (і запобігти проблемі):

NodeJS хешує представлення рядка UTF-8. Інші мови (наприклад, Python, PHP або PERL ...) мають хеширование рядка байтів.

Ми можемо додати бінарний аргумент, щоб використовувати рядок байтів.

Код:

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

Документація:

  • crypto.createHash (алгоритм [, параметри]): алгоритм залежить від доступних алгоритмів, підтримуваних версією OpenSSL на платформі.
  • hash.digest ([кодування]): кодування може бути "шестигранним", "latin1" або "base64". (основа 64 менше довша).

Ви можете отримати проблему за допомогою: sha256 ("\ xac"), "\ xd1", "\ xb9", "\ xe2", "\ xbb", "\ x93" тощо ...

  • Інші мови (як PHP, Python, Perl ...) та моє рішення з .update(data, "binary"):

    sha1("\xac") //39527c59247a39d18ad48b9947ea738396a3bc47
  • Nodejs за замовчуванням (без двійкових):

    sha1("\xac") //f50eb35d94f1d75480496e54f4b4a472a9148752

15

The cryptoМодуль робить це дуже легко.

Налаштування:

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

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

Використання:

sha256('Hello, world. ');

10

Тут ви можете порівняти всі підтримувані хеші на вашому обладнанні, підтримувані вашою версією node.js. Деякі - криптографічні, а деякі - лише для контрольної суми. Його обчислення "Hello World" 1 мільйон разів для кожного алгоритму. На кожен алгоритм може знадобитися приблизно 1-15 секунд (випробувано на стандартній обчислювальній машині Google з 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);  
}

Результат:
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-з-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


1
Що роблять RSA-префікси?
балуптон

7

Прості вкладиші:

Якщо ви хочете, щоб текстовий хеш UTF8:

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

Якщо ви хочете отримати той самий хеш із Python, PHP, Perl, Github:

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

Крім того, можна замінити 'sha256'з 'sha1', 'md5', 'sha256','sha512'


1

Враховуючи думки з http://www.thoughtcrime.org/blog/the-cryptographic-doom-principle/ (коротше: ПЕРШЕ шифрування, ТОЖЕ автентифікувати. Після цього ПЕРШИЙ перевірте, ТОЖЕ розшифруйте) Я реалізував наступне рішення у вузлі. 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); 
    }
}

Його можна перевірити за допомогою:

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

Сподіваюсь, це допомагає :-)


1

Я використовую blueimp-md5, який "Сумісний із середовищем на сервері, як-от Node.js, завантажувачами модулів, як RequireJS, Browrify або webpack та всі веб-браузери."

Використовуйте його так:

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

var myHashedString = createHash('GreensterRox');

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

Якщо передавати хешовані значення навколо на відкритому повітрі, завжди корисно солити їх, щоб людям було важче відтворити їх:

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

Навіть якщо хеш не для безпеки, ви можете використовувати sha замість md5. На мою думку, люди повинні зараз забути про md5, це вже в минулому!

Нормальний nodejs sha256 застарілий. Отже, у вас зараз є дві альтернативи:

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

Я вважаю за краще використовувати shajsзамість цього hash, тому що вважаю ша найкращою хеш-функцією в даний час, і вам зараз не потрібна інша хеш-функція. Отже, щоб отримати хеш-шестигранник, вам слід зробити щось на зразок наступного:

sha256.update('hello').digest('hex')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.