如何在node.js中获取字符串的sha1哈希值?

Eri*_*ric 94 javascript websocket node.js

我正在尝试创建一个用node.js编写的websocket服务器

为了使服务器工作,我需要获取字符串的SHA1哈希值.

我需要做的是在文档的第5.2.2节第35页中解释.

注意:例如,如果"Sec-WebSocket-Key" 客户端握手中的标头值为"dGhlIHNhbXBsZSBub25jZQ==",则服务器会附加字符串"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"以形成字符串"dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11".然后服务器将获取该字符串的SHA-1哈希值,给出值0xb3 0x7a 0x4f 0x2c 0xc0 0x62 0x4f 0x16 0x90 0xf6 0x46 0x06 0xcf 0x38 0x59 0x45 0xb2 0xbe 0xc4 0xea.然后对该值进行base64编码,以提供"s3pPLMBiTxaQ9kYGzzhZRbK+xOo="将在"Sec-WebSocket-Accept"标头中返回的值.

mae*_*ics 220

查看crypto.createHash()功能及相关hash.update()hash.digest()功能:

const crypto = require('crypto')
  , shasum = crypto.createHash('sha1');
shasum.update('foo');
console.log(shasum.digest('hex'));
// "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"
Run Code Online (Sandbox Code Playgroud)


mik*_*ana 22

必要条件:SHA1已损坏,您可以与普通创业加速器群组的AWS信用额发生冲突,但要回答您的问题:

var getSHA1ofJSON = function(input){
    return crypto.createHash('sha1').update(JSON.stringify(input)).digest('hex')
}
Run Code Online (Sandbox Code Playgroud)

然后:

getSHA1ofJSON('whatever')
Run Code Online (Sandbox Code Playgroud)

要么

getSHA1ofJSON(['whatever'])
Run Code Online (Sandbox Code Playgroud)

要么

getSHA1ofJSON({'this':'too'})
Run Code Online (Sandbox Code Playgroud)

  • 好主意.但请注意,所有对象(数组和null除外)都具有相同的sha1sum值,因为`Object.toString()`默认返回`[object Object]`.所以`sha1sum({})`===`sha1sum({"foo":"bar"})`===`sha1sum({"a":1})`等. (6认同)
  • @maerics:优点,最好使用JSON.stringify() (4认同)
  • 由于 haveibeenpwned.com API 需要 SHA1 哈希值,因此即使在今天也有完全正当的理由使用它。但还是谢谢你的回答! (3认同)
  • 在任何平台上,给定字符串的sha1应该是相同的.您使用JSON.stringify的实现正在改变原始字符串,而sha1sum("abcd")给出f805c8fb0d5c466362ce9f0dc798bd5b3b32d512,任何人都会期望81fe8bfe87576c3ecb22426f8e57847382917acf (2认同)
  • @Pierre 这是一个很好的观点。我认为根据您所说的,将函数命名为“sha1sum”是不准确的——这显然比普通的 sha1 做得更多。我在答案中重命名了该函数。 (2认同)
  • SHA1 仍然可以用于差异检查吗?并非所有哈希应用程序都与安全相关。我认为抛出诸如“SHA1 已损坏,您应该使用 sha256”之类的笼统声明具有误导性。SHA1 非常快,这是某些非安全相关应用程序的要求。 (2认同)

A-3*_*312 11

防止问题(错误哈希)的提示:

我经历过 NodeJS 正在对字符串的 UTF-8 表示进行哈希处理。其他语言(如 Python、PHP 或 PERL...)正在对字节字符串进行哈希处理。

我们可以添加二进制参数来使用字节字符串。

const crypto = require("crypto");

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

sha1("Your text ;)");
Run Code Online (Sandbox Code Playgroud)

您可以尝试使用:“\xac”、“\xd1”、“\xb9”、“\xe2”、“\xbb”、“\x93”等...

其他语言(Python、PHP...):

sha1("\xac") //39527c59247a39d18ad48b9947ea738396a3bc47
Run Code Online (Sandbox Code Playgroud)

节点:

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

  • ^^ @JossefHarush 的极其重要的评论!如果您在散列之前没有特别需要将文本编码为 latin1(例如,为了与 PHP 兼容),并且您的文本有可能包含 latin1 范围之外的 Unicode 符号(例如表情符号!),请不要使用 `binary` !在编码中使用“binary”或“latin1”将“丢失信息”并增加冲突的可能性!尝试上面的代码片段,例如这两个:“❤”和“⑤” (3认同)
  • `'binary'` - `'latin1'` 的别名 https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings (2认同)
  • @mckenzm true,但是,nodejs 中字符串文字的“正确”二进制表示形式是 utf8。这里的问题是使用“\xac”并期望二进制表示为“[0xAC]”,就像具有不同本机编码的其他语言一样。Node 使用 utf8,因此 utf8 源代码中的“\xac”(或“Ø”)被解释为“[0xC2, 0xAC]”,并且该数组的正确 sha1 由上面的代码生成。解决方法是首先读取二进制数据,因为不存在固有正确的字符串跨平台二进制表示形式。 (2认同)

Ale*_*pin 8

请在您的帖子评论中阅读并强烈考虑我的建议.话虽这么说,如果你还有充分的理由这样做,请查看Node的crpyto模块列表.它有用于处理sha1和base64的模块.


小智 5

您可以使用:

  const sha1 = require('sha1');
  const crypt = sha1('Text');
  console.log(crypt);
Run Code Online (Sandbox Code Playgroud)

安装:

  sudo npm install -g sha1
  npm install sha1 --save
Run Code Online (Sandbox Code Playgroud)