สตริงแฮช node.js?


325

ฉันมีสตริงที่ฉันต้องการแฮช วิธีที่ง่ายที่สุดในการสร้างแฮชใน 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
Frank Nocke

8
OP ต้องการแฮชสตริงไม่ใช่ไฟล์
blimpse

699

หากคุณเพียงแค่ต้องการ md5 แฮชสตริงง่ายๆที่ฉันพบว่างานนี้สำหรับฉัน

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

181
Woot Woot หากrequire('crypto').createHash('md5').update(STRING_TO_BE_HASHED).digest("hex")คุณมีสายการบินเดียว ไชโยเพื่อน!
balupton

3
ได้รับปัญหาบางอย่างโดยใช้.updateหลายครั้ง ( github.com/joyent/node/issues/749 ) เมื่อพยายามใช้timboooวิธีแก้ปัญหาโดยใช้ one-liner แก้ไขมัน (เพราะวัตถุแฮชถูกสร้างขึ้นใหม่ทุกครั้ง)
สูงสุด

มีวิธีใดในการเปลี่ยนความยาวของสตริง? ไม่เพียง 32 ตัวอักษร 64 หรือ 128 หรือตัวเลขอื่น
Mikel

@Mikel ลองดูหากมีอัลกอริธึมแฮชอื่น ๆ ที่เหมาะกับความต้องการของคุณ md5 จะเป็น 32 ตัวอักษรเสมอ
ไท

หากฉันมีสตริงจำนวนมากที่ต้องแฮชจะมีประสิทธิภาพน้อยกว่าในการโทรหา crypto.createHash แทนการใช้ผลลัพธ์ซ้ำอีกครั้ง
Michael

81

API โมดูลการเข้ารหัสของโหนดยังคงไม่เสถียร

ในฐานะเวอร์ชั่น 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 แทนที่จะนำมาเป็นโมดูลใหม่ทั้งหมด
Valjas

6
จากเอกสาร Node.js ปัจจุบัน: "ความเสถียร: 2 - ไม่เสถียรการเปลี่ยนแปลงของ API กำลังถูกกล่าวถึงสำหรับเวอร์ชันในอนาคตการเปลี่ยนแปลงการแตกหักจะลดลง" API ของโมดูลของฉันจะไม่เปลี่ยนแปลง เมื่อฉันแรกเขียนโมดูลไม่มี cryptoโมดูลที่สร้างขึ้นในแพลตฟอร์ม ข้อดีอีกอย่างคือคุณสามารถใช้โมดูลของฉันบนเซิร์ฟเวอร์เช่นเดียวกับฝั่งไคลเอ็นต์ แต่ทั้งหมดขึ้นอยู่กับคุณว่าคุณใช้ห้องสมุดอะไร
pvorb

7
บิลด์ Hash Crypto ให้ฉันด้วย 'แฮ็กอัพเดตล้มเหลว' BS ในที่สุดฉันก็ย้ายไปที่โมดูล MD5 และมันก็ใช้ได้ดี ยังง่ายต่อการโทร (เล็กน้อย) ขอบคุณ.
GJK

2
+1 สำหรับตัวเลือกที่อยู่ห่างจาก (2) - ลักษณะที่ไม่แน่นอนของ Crypto API!
หุ้น

1
ฉันได้แก้ไขปัญหา sha1 แปลก ๆ บนโหนด 0.11.x บนเครื่อง Windows ของฉันโดยการแลกเปลี่ยน crypto มาตรฐานที่ใช้สำหรับโมดูลนี้
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 ([การเข้ารหัส]):การเข้ารหัสสามารถเป็น 'hex', 'latin1' หรือ 'base64' (ฐาน 64 น้อยกว่า)

คุณสามารถรับปัญหาด้วย: sha256 ("\ xac"), "\ xd1", "\ xb9", "\ xe2", "\ xbb", "\ x93", ฯลฯ ...

  • ภาษาอื่น ๆ (เช่น PHP, Python, Perl ... ) และโซลูชันของฉันด้วย.update(data, "binary"):

    sha1("\xac") //39527c59247a39d18ad48b9947ea738396a3bc47
  • โหนดโดยปริยาย (ไม่มีไบนารี):

    sha1("\xac") //f50eb35d94f1d75480496e54f4b4a472a9148752

15

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 เก่า: 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
หม่า: 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
วังวน: 2578ms


1
ทำอะไรRSA-คำนำหน้าทำอย่างไร
balupton

7

Simple One Liners:

หากคุณต้องการแฮ็กข้อความ 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 . แม้ว่าtcrime.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, Browserify หรือ 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เพราะฉันถือว่า sha เป็นฟังก์ชันแฮชที่ดีที่สุดในปัจจุบันและคุณไม่ต้องการฟังก์ชันแฮชที่แตกต่างกันในตอนนี้ ดังนั้นหากต้องการแฮชเป็น hex คุณควรทำดังนี้:

sha256.update('hello').digest('hex')
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.