ciąg skrótu node.js?

325

Mam ciąg, który chcę mieszać. Jaki jest najprostszy sposób na wygenerowanie skrótu w node.js?

Hash służy do wersjonowania, a nie bezpieczeństwa.

Złupić
źródło

Odpowiedzi:

224

Spójrz na crypto.createHash (algorytm)

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);
});
dertkw
źródło
Co robi funkcja s.on ()? Czy rejestruje funkcję md5sum.update (d), aby była wykonywana za każdym razem, gdy odczytywane są dane z ReadStream?
DucRP
@YoniDor Czy próbowałeś fs.readsync ? - Trawienie w klasycznej pętli while, a następnie upewnij się, że zostało zrobione ... ➝ stackoverflow.com/a/21219407/444255
Frank Nocke
8
OP chce mieszać ciąg, a nie plik.
sterowiec
698

Jeśli chcesz po prostu skrótu md5, napisałem, że to działa dla mnie.

var crypto = require('crypto');
var name = 'braitsch';
var hash = crypto.createHash('md5').update(name).digest('hex');
console.log(hash); // 9b74c9897bac770ffc029102a200c5de
Braitsch
źródło
181
Woot, woot, jeśli masz require('crypto').createHash('md5').update(STRING_TO_BE_HASHED).digest("hex")liner. Zdrowie przyjacielu!
balupton,
3
Występowały problemy przy .updatewielokrotnym używaniu ( github.com/joyent/node/issues/749 ) podczas próby użycia timbooorozwiązania, używając naprawionego linku (ponieważ obiekt skrótu jest odtwarzany za każdym razem).
Max
Jakikolwiek sposób na zmianę długości łańcucha? Nie tylko 32 znaki, 64 lub 128 lub inny numer.
Mikel
@Mikel spróbuj, jeśli istnieją inne algorytmy mieszające, które odpowiadają Twoim potrzebom, md5 ma zawsze 32 znaki.
Wiąże
Jeśli mam wiele ciągów do mieszania, mniej wydajne jest nadal wywoływanie crypto.createHash zamiast ponownego wykorzystywania wyniku?
Michael
81

Interfejs API modułu kryptograficznego węzła jest nadal niestabilny.

Od wersji 4.0.0 natywny moduł Crypto nie jest już niestabilny. Z oficjalnej dokumentacji :

Crypto

Stabilność: 2 - Stabilny

Interfejs API okazał się zadowalający. Zgodność z ekosystemem NPM ma wysoki priorytet i nie zostanie zerwana, chyba że jest to absolutnie konieczne.

Dlatego należy uznać za bezpieczne korzystanie z natywnej implementacji bez zewnętrznych zależności.

Dla odniesienia, wspomniane poniżej moduły zostały zaproponowane jako alternatywne rozwiązania, gdy moduł Crypto był nadal niestabilny.


Możesz także użyć jednego z modułów sha1 lub md5, które oba wykonują zadanie.

$ npm install sha1

i wtedy

var sha1 = require('sha1');

var hash = sha1("my message");

console.log(hash); // 104ab42f1193c336aa2cf08a2c946d5c6fd0fcdb

lub

$ npm install md5

i wtedy

var md5 = require('md5');

var hash = md5("my message");

console.log(hash); // 8ba6c19dc1def5702ff5acbf2aeea5aa

(MD5 jest niepewny, ale często używany przez usługi takie jak Gravatar.)

Interfejs API tych modułów się nie zmieni!

pvorb
źródło
9
Myślę, że o wiele łatwiej i wydajniej jest używać Crypto niż wprowadzać zupełnie nowy moduł.
Valjas
6
Z bieżących dokumentów Node.js: „Stabilność: 2 - niestabilna; zmiany API są omawiane w przyszłych wersjach. Przełamywanie zmian zostanie zminimalizowane”. Interfejs API mojego modułu się nie zmieni. Kiedy początkowo napisał moduł, nie było żadnego crypto moduł wbudowany w platformę. Kolejną zaletą jest to, że możesz używać mojego modułu zarówno na serwerze, jak i po stronie klienta. Ale od Ciebie zależy, jakiej biblioteki użyjesz.
pvorb
7
Kompilacja skrótów Crypto ciągle dawała mi BS „aktualizacja nieudana”. W końcu przeszedłem do modułu MD5 i działało dobrze. Łatwiej też zadzwonić (nieco). Dziękuję Ci.
GJK,
2
+1 za opcję, która pozostaje z dala od (2) - niestabilnej natury Crypto API!
Geek Stocks
1
Naprawiłem dziwny problem sha1 w węźle 0.11.x na moim komputerze z systemem Windows, zmieniając standardowe użycie szyfrowania dla tego modułu.
Bartvds
24
sha256("string or binary");

Wystąpił problem z inną odpowiedzią. binaryRadzę ustawić argument kodowania, aby używał łańcucha bajtów i zapobiegał różnym hashom między Javascript (NodeJS) a innymi językami / usługami takimi jak Python, PHP, Github ...

Jeśli nie użyjesz tego kodu, możesz uzyskać inny skrót między NodeJS i Python ...

Jak uzyskać taki sam skrót, jak Python, PHP, Perl, Github (i zapobiec problemowi):

NodeJS hashuje reprezentację ciągu UTF-8. Inne języki (jak Python, PHP lub PERL ...) mieszają ciąg bajtów.

Możemy dodać argument binarny, aby użyć ciągu bajtów.

Kod :

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

Dokumentacja:

  • crypto.createHash (algorytm [, opcje]): Algorytm zależy od dostępnych algorytmów obsługiwanych przez wersję OpenSSL na platformie.
  • hash.digest ([kodowanie]): Kodowanie może być „hex”, „latin1” lub „base64”. (podstawa 64 jest mniej dłuższa).

Możesz uzyskać problem z: sha256 („\ xac”), „\ xd1”, „\ xb9”, „\ xe2”, „\ xbb”, „\ x93” itp.

  • Inne języki (jak PHP, Python, Perl ...) i moje rozwiązanie z .update(data, "binary"):

    sha1("\xac") //39527c59247a39d18ad48b9947ea738396a3bc47
  • Domyślnie Nodejs (bez pliku binarnego):

    sha1("\xac") //f50eb35d94f1d75480496e54f4b4a472a9148752
A-312
źródło
15

cryptoModuł sprawia, że to bardzo łatwe.

Ustawiać:

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

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

Stosowanie:

sha256('Hello, world. ');
sdgfsdh
źródło
10

Tutaj możesz przetestować wszystkie obsługiwane skróty na twoim sprzęcie, obsługiwane przez twoją wersję node.js. Niektóre są kryptograficzne, a niektóre służą tylko do sumy kontrolnej. Jego obliczenie „Hello World” 1 milion razy dla każdego algorytmu. Każdy algorytm może potrwać około 1-15 sekund (testowany na standardowym silniku obliczeniowym Google z 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);  
}

Wynik:
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-z 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

użytkownik3077458
źródło
1
Co robią RSA-przedrostki?
balupton
7

Proste One Liners:

Jeśli chcesz mieszać tekst UTF8:

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

Jeśli chcesz uzyskać ten sam skrót z Python, PHP, Perl, Github:

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

Można również wymienić 'sha256'z 'sha1', 'md5', 'sha256','sha512'

kurczaki
źródło
1

Biorąc pod uwagę przemyślenia z http://www.thoughtcrime.org/blog/the-cryptographic-doom-principle/ (w skrócie: PIERWSZE szyfrowanie, następnie uwierzytelnianie. Następnie PIERWSZE sprawdzenie, a następnie odszyfrowanie) Wdrożiłem następujące rozwiązanie w węźle. 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); 
    }
}

Można to przetestować za pomocą:

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

Mam nadzieję że to pomoże :-)

batomaeus
źródło
1

Używam blueimp-md5, który jest „Kompatybilny ze środowiskami serwerowymi, takimi jak Node.js, modułami ładującymi, takimi jak RequireJS, Browserify lub webpack i wszystkimi przeglądarkami internetowymi”.

Użyj tego w ten sposób:

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

var myHashedString = createHash('GreensterRox');

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

Jeśli przekazywanie wartości mieszanych jest otwarte, zawsze dobrym pomysłem jest ich solenie, aby ludziom było trudniej je odtworzyć:

createHash(myString){
    var salt = 'HnasBzbxH9';
    return md5(myString+salt);
}
GreensterRox
źródło
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));
Phap
źródło
-1

Nawet jeśli skrót nie służy bezpieczeństwu, możesz użyć sha zamiast md5. Moim zdaniem ludzie powinni na razie zapomnieć o md5, to już przeszłość!

Normalny nodejs sha256 jest przestarzały. Masz na razie dwie alternatywy:

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

Wolę używać shajszamiast hash, ponieważ uważam sha za najlepszą funkcję skrótu w dzisiejszych czasach i na razie nie potrzebujesz innej funkcji skrótu. Aby uzyskać skrót w kodzie szesnastkowym, wykonaj następujące czynności:

sha256.update('hello').digest('hex')
Maf
źródło