PHP base64 encoding drops incorrect answer

166 Views Asked by At

I'm currently working on a website, which must implement a web-socket server. I am using PHP to make the server. I extracted a Sec-websocket-key from the clients response, then I hashed it using the PHP sha1() command.

The problem is that when I want to base64_encode it then it gives an incorrect accept key which is an error. Was there a change in base64_encode command?

Thank you for the answers!

This is just a test code, it doesn't allow for multiple clients:

$address = "127.0.0.1";
$port = 9000;

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sock, $address, $port);
socket_listen($sock);

$client = socket_accept($sock);

$handshake = Array();

$response = socket_read($client, 1024);

$handshake = split("\r\n", $response);

$socketKey = split(" ", $handshake[11]);

$rawAccept =  socketKey[1] . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

$rawAccept = str_replace(" ", "", $rawAccept);

$rawSha1Accept = sha1($rawAccept);

$accept = base64_encode($rawSha1Accept);

$upgrade = "HTTP/1.1 101 Switching Protocols\r\n" .
            "Upgrade: websocket\r\n" .
            "Connection: Upgrade\r\n" .
            "Sec-WebSocket-Accept: $accept\r\n\r\n";

socket_write($client, $upgrade, 1024);
2

There are 2 best solutions below

1
On BEST ANSWER

The function sha1() will already encode the hash value, so you should probably calculate the binary hash before encoding:

$rawSha1Accept = sha1($rawAccept, true); // Note the second parameter
$accept = base64_encode($rawSha1Accept);
0
On

I believe the error could be in this line:

$rawAccept =  socketKey[1] . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

I think socketKey[1] should be just socketKey, but I've written some untested code below which should help show you how to get the key and create the correct accept key.

$address = "127.0.0.1";
$port = 9000;

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sock, $address, $port);
socket_listen($sock);

$client = socket_accept($sock);

$response = socket_read($client, 1024);

if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $response, $match))
{
    $key = $match[1];
}

$sha = sha1($key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true);
$acccept = base64_encode($sha);

$upgrade = "HTTP/1.1 101 Switching Protocols\r\n" .
        "Upgrade: websocket\r\n" .
        "Connection: Upgrade\r\n" .
        "Sec-WebSocket-Accept: $accept\r\n\r\n";

socket_write($client, $upgrade, 1024);