Node.js'de bir dizenin sha1 karmasını nasıl alabilirim?


108

Node.js ile yazılmış bir websocket sunucusu oluşturmaya çalışıyorum

Sunucuyu çalıştırmak için bir dizenin SHA1 karmasını almam gerekiyor.

Yapmam gerekenler, belgelerin Bölüm 5.2.2 sayfa 35'te açıklanmıştır .

NOT: Örnek olarak, "Sec-WebSocket-Key" istemcinin el sıkışmasındaki üstbilgi değeri "dGhlIHNhbXBsZSBub25jZQ=="olsaydı, sunucu "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"dizeyi oluşturmak için dizeyi eklerdi "dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11". Sunucu daha sonra bu dizenin SHA-1 karmasını alarak 0xb3 0x7a 0x4f 0x2c 0xc0 0x62 0x4f 0x16 0x90 0xf6 0x46 0x06 0xcf 0x38 0x59 0x45 0xb2 0xbe 0xc4 0xea değerini verir. Bu değer daha sonra başlıkta "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="döndürülecek olan değeri vermek için base64 olarak kodlanır "Sec-WebSocket-Accept".


9
Ben ediyorum son derece mükemmel kullanmanızı tavsiye socket.io kütüphanesi yerine kendi haddeleme. Bu yalnızca kapsamlı bir şekilde test edilip yamalanmakla kalmaz, aynı zamanda çoğu tarayıcıyı (WebSocket API'sı olmayanlar) çeşitli yöntemlerle destekler.
Alex Turpin

1
Gelecekteki ziyaretçiler için iyi bir referans: stackoverflow.com/questions/9407892/…
Damodaran

Yanıtlar:



32

Zorunlu: SHA1 bozuk , 45.000 USD karşılığında SHA1 çarpışmalarını hesaplayabilirsiniz . Kullanmalısınız sha256:

var getSHA256ofJSON = function(input){
    return crypto.createHash('sha256').update(JSON.stringify(input)).digest('hex')
}

Sorunuzu yanıtlamak ve SHA1 hash'i oluşturmak için:

const INSECURE_ALGORITHM = 'sha1'
var getInsecureSHA1ofJSON = function(input){
    return crypto.createHash(INSECURE_ALGORITHM).update(JSON.stringify(input)).digest('hex')
}

Sonra:

getSHA256ofJSON('whatever')

veya

getSHA256ofJSON(['whatever'])

veya

getSHA256ofJSON({'this':'too'})

Resmi düğüm belgeleri açık crypto.createHash()


7
İyi bir fikir. Bununla birlikte, tüm nesnelerin (diziler ve boş hariç) varsayılan olarak Object.toString()döndürüldüğünden beri aynı sha1sum değerine sahip olacağını [object Object]unutmayın. Yani sha1sum({})=== sha1sum({"foo":"bar"})=== sha1sum({"a":1}), vb.
maerics

sha1 (JSON.stringify ("bir dizi")) => sha1 ("\" bazı dizeler \ "") kesinlikle beklenmeyen ve çapraz platform olmayan. Bazen iyinin düşmanı daha iyidir.
Pierre

3
belirli bir dizenin sha1'inin herhangi bir platformda aynı olması beklenir. Herkes 81fe8bfe87576c3ecb22426f8e57847382917acf beklediğiniz yerde JSON.stringify orijinal dize ve sha1sum ( "abcd") değiştiriyor kullanarak uygulama f805c8fb0d5c466362ce9f0dc798bd5b3b32d512 verir
Pierre

2
@Pierre Bu mükemmel bir nokta. sha1sumSöyledikleriniz göz önüne alındığında , işlevi adlandırmanın yanlış olduğunu düşünüyorum - bu açıkça normal bir sha1'in yapacağından daha fazlasını yapıyor. Cevapta işlevi yeniden adlandırdım.
mikemaccana

Gibi standart 80-yuvarlak SHA-1'e göre bugün bilinen hiçbir çarpışma vardır stackoverflow.com/a/3476791/1236215
kzahel


7

Sorunu önlemek için ipuçları (bozuk hash):

NodeJS'nin dizenin UTF-8 temsiline hashing uyguladığını deneyimledim. Diğer diller (Python, PHP veya PERL ... gibi) bayt dizesine hashing uyguluyor.

Bayt dizesini kullanmak için ikili argüman ekleyebiliriz .

const crypto = require("crypto");

function sha1(data) {
    return crypto.createHash("sha1").update(data, "binary").digest("hex");
}

sha1("Your text ;)");

Şunları deneyebilirsiniz: "\ xac", "\ xd1", "\ xb9", "\ xe2", "\ xbb", "\ x93", vb ...

Diğer diller (Python, PHP, ...):

sha1("\xac") //39527c59247a39d18ad48b9947ea738396a3bc47

Nodejs:

sha1 = crypto.createHash("sha1").update("\xac", "binary").digest("hex") //39527c59247a39d18ad48b9947ea738396a3bc47
//without:
sha1 = crypto.createHash("sha1").update("\xac").digest("hex") //f50eb35d94f1d75480496e54f4b4a472a9148752

1
'binary'- 'latin1' nodejs.org/api/…
Jossef Harush

1
^^ @JossefHarush'tan son derece önemli açıklama! Karma oluşturmadan önce metni latin1 olarak kodlamanız gerekmiyorsa (ör. Tam olarak PHP ile uyumluluk için) ve metninizin latin1 aralığı dışında (ör. Emoji!) Unicode semboller içermesi ihtimali varsa, kullanmayın binary! Kodlamada binaryveya latin1kodlamada kullanmak bilgileri kaybedecek ve çarpışma olasılığını artıracaktır! Örneğin, yukarıdaki iki parçacığı deneyin: ve
2019

Tüm karmalar ikili veriler üzerinde yapılır. Yaşadığınız sorun, bahsettiğiniz diğer dillerin UTF-8 kullanmamasıdır, tersi değil. Latin1 dışında bir şeyi hash etmeye çalıştığınızda bu çok belirgin hale gelecektir. Özellikle PHP söz konusu olduğunda, kodlama tamamen kaynak tarafından belirlenir, örneğin sabit kodlanmış metin için metin dosyasının kendisi gibi. Perl, UTF-8'i kullanmak için biraz ağır kaldırmaya ihtiyaç duyabilir.
Ryan Hanekamp

3

Kullanabilirsiniz:

  const sha1 = require('sha1');
  const crypt = sha1('Text');
  console.log(crypt);

Kurulum için:

  sudo npm install -g sha1
  npm install sha1 --save

Merhaba user944550, hoş geldiniz. Lütfen daha fazla bilgi eklemeyi düşünün.
Tiago Martins Peres 李大仁
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.