node.js에서 문자열의 sha1 해시를 어떻게 얻을 수 있습니까?


108

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 값을 제공합니다. 이 값은 헤더에 "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="반환되는 값을 제공하기 위해 base64로 인코딩 "Sec-WebSocket-Accept"됩니다.


9
나는 것 매우 우수한 사용하는 것이 좋습니다 socket.io의 라이브러리를 대신 자신의 압연. 이것은 광범위하게 테스트되고 패치되었을뿐만 아니라 다양한 방법을 통해 대부분의 브라우저 (WebSocket API가없는 이벤트)를 지원합니다.
Alex Turpin

1
미래 방문자를위한 좋은 참고 자료 : stackoverflow.com/questions/9407892/…
Damodaran 2013

답변:



32

필수 : SHA1이 손상 되었습니다. 45,000 USD에 대해 SHA1 충돌을 계산할 수 있습니다 . 다음을 사용해야합니다 sha256.

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

질문에 답하고 SHA1 해시를 만들려면 :

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

그때:

getSHA256ofJSON('whatever')

또는

getSHA256ofJSON(['whatever'])

또는

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

공식 노드 문서 crypto.createHash()


7
좋은 생각. 그러나 모든 개체 (배열 및 null 제외)는 기본적으로 Object.toString()반환 되므로 동일한 sha1sum 값을 갖습니다 [object Object]. 그래서 sha1sum({})=== sha1sum({"foo":"bar"})=== sha1sum({"a":1}), etc.
maerics

sha1 (JSON.stringify ( "some string")) => sha1 ( "\"some string \ "") 절대적으로 예상되지 않고 교차 플랫폼이 아닙니다. 때로는 선의 적이 더 좋습니다.
Pierre

3
주어진 문자열의 sha1은 모든 플랫폼에서 동일해야합니다. JSON.stringify를 사용한 구현은 원래 문자열을 변경하고 sha1sum ( "abcd")는 f805c8fb0d5c466362ce9f0dc798bd5b3b32d512를 제공합니다. 여기서 누구나 81fe8bfe87576c3ecb22426f8e57847382917acf
Pierre는

2
@Pierre 그것은 훌륭한 포인트입니다. 나는 sha1sum당신이 말한 것을 감안할 때 함수 이름을 지정하는 것이 정확하지 않다고 생각합니다 . 이것은 일반 sha1이하는 것보다 분명히 더 많은 일을합니다. 대답에서 함수의 이름을 변경했습니다.
mikemaccana



7

문제 방지를위한 팁 (잘못된 해시) :

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

"\ xac", "\ xd1", "\ xb9", "\ xe2", "\ xbb", "\ x93"등으로 시도 할 수 있습니다.

기타 언어 (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
^^ @JossefHarush의 매우 중요한 발언! 해싱하기 전에 텍스트를 latin1로 인코딩 할 필요가없고 (예 : PHP와의 호환성을 위해 정확히) 텍스트에 latin1 범위를 벗어난 유니 코드 기호 (예 : 이모 지!)가 포함되어있을 가능성이있는 경우에는 binary! 사용 binary또는 latin1인코딩에 할 정보가 손실 및 충돌의 가능성을 증가! 예를 들어,이 두 가지에 위의 코드 조각을 시도 하고
CBR

모든 해시는 이진 데이터에서 수행됩니다. 겪고있는 문제는 언급 한 다른 언어가 UTF-8을 사용하지 않는다는 것입니다. 이것은 Latin1 외부에서 무언가를 해시하려고하면 매우 분명해질 것입니다. 특히 PHP의 경우 인코딩은 하드 코딩 된 텍스트의 텍스트 파일 자체와 같이 소스에 의해 전적으로 결정됩니다. Perl은 UTF-8을 사용하기 위해 약간의 작업이 필요할 수 있습니다.
Ryan Hanekamp

3

당신이 사용할 수있는:

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

설치 :

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

안녕하세요 user944550, 환영합니다. 더 많은 정보를 추가해보십시오.
Tiago Martins Peres 李大仁
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.