gpt4 book ai didi

node.js - Sec-WebSocket-Accept 值的 Base64 编码

转载 作者:搜寻专家 更新时间:2023-10-31 22:33:08 26 4
gpt4 key购买 nike

不久前,我开始尝试使用 WebSockets 和 Node.js 来处理后端。它工作正常,但现在当我返回时,协议(protocol)已经更新,我无法再让它正常工作。

具体来说,问题是 Sec-WebSocket-Accept header 。我在计算它时似乎做错了什么,尽管我无法真正理解那可能是什么。据我所知,我正在关注 instructions on Wikipedia到点。

这是我的代码:

var magicString = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
var secWsKey = req.headers['sec-websocket-key'];
var hash = require('crypto')
.createHash('SHA1')
.update(secWsKey + magicString)
.digest('hex');
var b64hash = new Buffer(hash).toString('base64');
var handshake = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" +
"Upgrade: WebSocket\r\n" +
"Connection: Upgrade\r\n" +
"Sec-WebSocket-Accept: " + b64hash + "\r\n" +
"\r\n";

socket.write(handshake);

示例连接:

// The incoming headers
{ upgrade: 'websocket',
connection: 'Upgrade',
host: 'localhost:8888',
origin: 'http://localhost:8888',
'sec-websocket-key': '4aRdFZG5uYrEUw8dsNLW6g==',
'sec-websocket-version': '13' }

// The outgoing handshake
HTTP/1.1 101 Switching Protocols
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Accept: YTYwZWRlMjQ4NWFhNzJiYmRjZTQ5ODI4NjUwMWNjNjE1YTM0MzZkNg==

// Result: Error during WebSocket handshake: Sec-WebSocket-Accept mismatch

对此进行了深入研究,我尝试在 wiki 中复制计算出的哈希值,但失败了。

var hash = require('crypto')
.createHash('SHA1')
.update('x3JJHMbDL1EzLkh9GBhXDw==258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
.digest('hex');

// Result : 1d29ab734b0c9585240069a6e4e3e91b61da1969
// Expected: 1d29ab734b0c9585240069a6e4e3e91b61da1969

var buf = new Buffer(hash).toString('base64');

// Result : MWQyOWFiNzM0YjBjOTU4NTI0MDA2OWE2ZTRlM2U5MWI2MWRhMTk2OQ==
// Expected: HSmrc0sMlYUkAGmm5OPpG2HaGWk=

如您所见,SHA1 哈希是正确的,但 base64 编码不是。看着this answer ,看来我会做对的。我在 PHP 中尝试了相同的过程并且得到了相同的结果,很明显我做错了。

我正在运行 Node.js v0.6.8。

越来越近

进一步试验我更熟悉的 PHP,并从 shell 中 printf 的行为中得出,我想出了这个工作片段:

$hash = sha1('x3JJHMbDL1EzLkh9GBhXDw==258EAFA5-E914-47DA-95CA-C5AB0DC85B11');
$hashdec = '';
for ($i = 0; $i < strlen($hash); $i += 2) {
$hashdec .= chr(hexdec(substr($hash, $i, 2)));
};
echo base64_encode($hashdec);
// Result : HSmrc0sMlYUkAGmm5OPpG2HaGWk=
// Expected: HSmrc0sMlYUkAGmm5OPpG2HaGWk=

然后我尝试在 JavaScript 中复制它,但无济于事。

var magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
var key = "4aRdFZG5uYrEUw8dsNLW6g==";
var magic_key = magic + key;
var hash = require('crypto').createHash('sha1').update(magic_key).digest('hex');
var buf = new Buffer(hash.length / 2);

for (var i = 0; i < hash.length; i += 2) {
var token = hash.substr(i, 2);
var int = parseInt(token.toString(16), 16);
var chr = String.fromCharCode(int);

buf.write(chr);
}

console.log(buf.toString('base64'));

// Result : w53dAAEAAADBIIAFAQAAAGGAtwA=
// Expected: HSmrc0sMlYUkAGmm5OPpG2HaGWk=

最佳答案

有时 reading the manual实际上有帮助。

hash.digest([encoding])

Calculates the digest of all of the passed data to be hashed. The encoding can be 'hex', 'binary' or 'base64'.

(强调我的。)

所以问题解决了,改代码为:

var magicString = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
var secWsKey = req.headers['sec-websocket-key'];
var hash = require('crypto')
.createHash('SHA1')
.update(secWsKey + magicString)
.digest('base64'); // <- see that, silly.
var handshake = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" +
"Upgrade: WebSocket\r\n" +
"Connection: Upgrade\r\n" +
"Sec-WebSocket-Accept: " + hash + "\r\n" +
"\r\n";

socket.write(handshake);

是时候感到愚蠢了。 (再次。)

关于node.js - Sec-WebSocket-Accept 值的 Base64 编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8990444/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com