PHP 7.4.3 SSL WSS通过迭代搜索未引用的密钥

问题描述

我正在尝试在服务器上使用websocket。问题似乎是我的证书,但错误消息显示PHP正在搜索我未指定的文件。直接在下面的是下面进一步给出的代码输出。请参考https://www.php.net/manual/en/context.ssl.php进行参考。

8888
WSS
Context Created
stream_socket_server Created
....1,stream would like to be processed.

PHP Warning:  stream_socket_accept(): Unable to set private key file '/etc/letsencrypt/archive/example.org/fullchain1.pem' in /var/www/carbonPHP.com/server.PHP on line 108
PHP Warning:  stream_socket_accept(): Failed to enable crypto in /var/www/example.com/server.PHP on line 108 
PHP Warning:  stream_socket_accept(): accept Failed: Success in /var/www/example.com/server.PHP on line 108
stream_socket_accept Failed

我正在查看以上文档,并尝试了许多不同的配置组合。查看上面的代码输出,我看到它正在搜索'fullchain1.pem',但是我为 stream_context_create 提供了'fullchain.pem'。当用户实际连接时,它不会被使用并在 stream_select 之前发出警告。 Safari实际上为我提供了错误消息 WebSocket网络错误:Osstatus错误-9806 的详细信息。这是一个通用的连接错误,因为PHP失败了。我使用let-encrypt生成密钥文件,并进行了一些探索,使我进入了该文件夹。我已经尝试了所有文件,但没有一个起作用。

root@blackhat:/etc/letsencrypt/live/example.org# ls
README  cert.pem  chain.pem  fullchain.pem  fullchain1.pem  privkey.pem
root@blackhat:/etc/letsencrypt/live/example.org# rm fullchain1.pem 
root@blackhat:/etc/letsencrypt/live/example.org# cat README 
This directory contains your keys and certificates.

`privkey.pem`  : the private key for your certificate.
`fullchain.pem`: the certificate file used in most server software.
`chain.pem`    : used for OCSP stapling in Nginx >=1.3.7.
`cert.pem`     : will break many server configurations,and should not be used
                 without reading further documentation (see link below).

移至代码。 *请知道SSL已关闭,该服务才能在tcp上正确运行。

PHP server.PHP

/server.PHP

#!/usr/bin/PHP
<?PHP

const TEXT = 0x1;
const BINARY = 0x2;
const CLOSE = 0x8;
const PING = 0x9;
const PONG = 0xa;
const HOST = '0.0.0.0';
const PORT = 8888;
const SSL = true;
const CERT = '/etc/letsencrypt/live/example.org/fullchain.pem';
const PASS = '';

print PORT . PHP_EOL . (SSL ? 'WSS' : 'WS') . PHP_EOL;

if (SSL) {

    //SSLCertificateFile /etc/letsencrypt/live/example.org/fullchain.pem
    //SSLCertificateKeyFile /etc/letsencrypt/live/example.org/privkey.pem

    $context = stream_context_create([
        'ssl' => [
            //'cafile' => __DIR__ . DIRECTORY_SEParaTOR . 'certificate.crt','local_cert' => CERT,//'peer_fingerprint' => PEER_FINGERPRINT,'CURLOPT_VERBOSE' => true,'verify_peer' => true,'verify_peer_name' => false,'allow_self_signed' => false,'verify_depth'  => 5,//'CN_match'      => 'carbonPHP.com','disable_compression' => true,'SNI_enabled'         => true,'ciphers'             => 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK'
        ]
    ]);

    print 'Context Created' . PHP_EOL;

    $protocol = 'ssl';
} else {
    $context = stream_context_create();
    $protocol = 'tcp';
}

$socket = stream_socket_server("$protocol://" . HOST . ':' . PORT,$errorNumber,$errorString,STREAM_SERVER_BIND | STREAM_SERVER_LISTEN,$context);

print 'stream_socket_server Created' . PHP_EOL;

if (!$socket) {
    echo "$errorString ($errorNumber)<br />\n";
} else {
    $master[] = $socket;
    while (true) {
        $read = $master;

        $mod_fd = stream_select($read,$_w,$_e,5);  // returns number of file descriptors modified

        if ($mod_fd === 0) {
            print '.';
            continue;
        }

        print "$mod_fd,stream would like to be processed.\n\n";

        foreach ($read as $connection) {

            if ($connection === $socket) { // accepting a new connection?

                $conn = stream_socket_accept($socket);

                if (false === $conn) {
                    print "stream_socket_accept Failed\n";
                    continue;
                }


                if (!handshake($conn)) {
                    fclose($conn);
                    continue;
                }

                fwrite($conn,encode('Hello! The time is ' . date('n/j/Y g:i a') . "\n"));
                $master[] = $conn;
                continue;

            }

            $data = decode($connection);

            switch ($data['opcode']) {
                case CLOSE:
                    $key_to_del = array_search($connection,$master,false);
                    @fclose($connection);
                    unset($master[$key_to_del]);
                    break;

                case PING :
                    @fwrite($connection,encode('',PONG));
                    break;

                case TEXT:
                    print $data['payload']->name . ',has sent :: ' . $data['payload']->message . PHP_EOL;

                    foreach ($master as $user) {
                        //  connection === $user and continue;  // but we dont hav this optimization on the front end

                        @fwrite($user,encode([
                            'type' => 'usermsg','name' => $data['payload']->name,'message' => $data['payload']->message,'color' => $data['payload']->color
                        ]));
                    }
                    break;
                default:
                    break;
            }
        }
    }
}

function handshake($socket): bool
{
    $headers = [];

    $lines = preg_split("/\r\n/",@fread($socket,4096));

    foreach ($lines as $line) {
        $line = rtrim($line);
        if (preg_match('/\A(\S+): (.*)\z/',$line,$matches)) {
            $headers[$matches[1]] = $matches[2];
        }
    }

    if (!isset($headers['Sec-WebSocket-Key'])) {
        return false;
    }

    $secKey = $headers['Sec-WebSocket-Key'];
    $secAccept = base64_encode(pack('H*',sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));

    $response = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
        "Upgrade: websocket\r\n" .
        "Connection: Upgrade\r\n" .
        "WebSocket-Origin: " . HOST . "\r\n" .
        "WebSocket-Location: wss://" . HOST . ":" . PORT . "/\r\n" .
        "Sec-WebSocket-Accept:$secAccept\r\n\r\n";

    try {
        return fwrite($socket,$response);
    } catch (Exception $e) {
        return false;
    }
}

function encode($message,$opCode = TEXT): string
{
    $rsv1 = 0x0;
    $rsv2 = 0x0;
    $rsv3 = 0x0;

    $message = json_encode($message);

    $length = strlen($message);

    $out = chr((0x1 << 7) | ($rsv1 << 6) | ($rsv2 << 5) | ($rsv3 << 4) | $opCode);

    if (0xffff < $length) {
        $out .= chr(0x7f) . pack('NN',$length);
    } elseif (0x7d < $length) {
        $out .= chr(0x7e) . pack('n',$length);
    } else {
        $out .= chr($length);
    }

    return $out . $message;
}

function decode($socket): array
{
    if (!$socket || !is_resource($socket)) {
        return [
            'opcode' => CLOSE,'payload' => ''
        ];
    }

    $out = [];
    $read = @fread($socket,1);

    if (empty($read)) {
        return [
            'opcode' => CLOSE,'payload' => ''
        ];
    }

    $handle = ord($read);
    $out['fin'] = ($handle >> 7) & 0x1;
    $out['rsv1'] = ($handle >> 6) & 0x1;
    $out['rsv2'] = ($handle >> 5) & 0x1;
    $out['rsv3'] = ($handle >> 4) & 0x1;
    $out['opcode'] = $handle & 0xf;

    if (!\in_array($out['opcode'],[TEXT,BINARY,CLOSE,PING,PONG],true)) {
        return [
            'opcode' => '','payload' => '','error' => 'unkNown opcode (1003)'
        ];
    }

    $handle = ord(fread($socket,1));
    $out['mask'] = ($handle >> 7) & 0x1;
    $out['length'] = $handle & 0x7f;
    $length = &$out['length'];

    if ($out['rsv1'] !== 0x0 || $out['rsv2'] !== 0x0 || $out['rsv3'] !== 0x0) {
        return [
            'opcode' => $out['opcode'],'error' => 'protocol error (1002)'
        ];
    }

    if ($length === 0) {
        $out['payload'] = '';
        return $out;
    }

    if ($length === 0x7e) {
        $handle = unpack('nl',fread($socket,2));
        $length = $handle['l'];
    } elseif ($length === 0x7f) {
        $handle = unpack('N*l',8));
        $length = isset($handle['l2']) ? $handle['l2'] : $length;

        if ($length > 0x7fffffffffffffff) {
            return [
                'opcode' => $out['opcode'],'error' => 'content length mismatch'
            ];
        }
    }

    if ($out['mask'] === 0x0) {
        $msg = '';
        $readLength = 0;

        while ($readLength < $length) {
            $toRead = $length - $readLength;
            $msg .= fread($socket,$toRead);

            if ($readLength === strlen($msg)) {
                break;
            }

            $readLength = strlen($msg);
        }

        $out['payload'] = $msg;
        return $out;
    }

    $maskN = array_map('ord',str_split(fread($socket,4)));
    $maskC = 0;

    $bufferLength = 1024;
    $message = '';

    for ($i = 0; $i < $length; $i += $bufferLength) {
        $buffer = min($bufferLength,$length - $i);
        $handle = fread($socket,$buffer);

        for ($j = 0,$_length = strlen($handle); $j < $_length; ++$j) {
            $handle[$j] = chr(ord($handle[$j]) ^ $maskN[$maskC]);
            $maskC = ($maskC + 1) % 4;
        }

        $message .= $handle;
    }

    $out['payload'] = json_decode($message);
    return $out;
}

这里是在tcp下工作的客户端。

PHP -S 127.0.0.1:88 index.PHP

/index.PHP

<!DOCTYPE html>
<html>
<head>
    <Meta charset='UTF-8'/>
    <style type="text/css">
        <!--
        .chat_wrapper {
            width: 500px;
            margin-right: auto;
            margin-left: auto;
            background: #CCCCCC;
            border: 1px solid #999999;
            padding: 10px;
            font: 12px 'lucida grande',tahoma,verdana,arial,sans-serif;
        }

        .chat_wrapper .message_Box {
            background: #FFFFFF;
            height: 150px;
            overflow: auto;
            padding: 10px;
            border: 1px solid #999999;
        }

        .chat_wrapper .panel input {
            padding: 2px 2px 2px 5px;
        }

        .system_msg {
            color: #BDBDBD;
            font-style: italic;
        }

        .user_name {
            font-weight: bold;
        }

        .user_message {
            color: #88B6E0;
        }

        -->
    </style>
</head>
<body>
<?PHP
$colours = array('007AFF','FF7000','15E25F','CFC700','CF1100','CF00BE','F00');
$user_colour = array_rand($colours);
?>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

<script language="javascript" type="text/javascript">
  $(document).ready(function () {
    //create a new WebSocket object.
    let wsUri = "wss://carbonPHP.com:8888/test.PHP";
    let websocket = new WebSocket(wsUri);

    websocket.onopen = function (ev) { // connection is open
      $('#message_Box').append("<div class=\"system_msg\">Connected!</div>"); //notify user
    };

    $('#send-btn').click(function () { //use clicks message send button
      let mymessage = $('#message').val(),//get message text
        myname = $('#name').val(); //get user name

      if (myname === "") { //empty name?
        alert("Enter your Name please!");
        return;
      }
      if (mymessage === "") { //emtpy message?
        alert("Enter Some message Please!");
        return;
      }

      //prepare json data
      let msg = {
        message: mymessage,name: myname,color: '<?=$colours[$user_colour] ?>'
      };
      //convert and send data to server
      websocket.send(JSON.stringify(msg));
    });

    //#### Message received from server?
    websocket.onmessage = function (ev) {
      let msg = JSON.parse(ev.data),//PHP sends Json data
        type = msg.type,//message type
        umsg = msg.message,//message text
        uname = msg.name,//user name
        ucolor = msg.color; //color

      if (type === 'usermsg') {
        $('#message_Box').append("<div><span class=\"user_name\" style=\"color:#" + ucolor + "\">" + uname + "</span> : <span class=\"user_message\">" + umsg + "</span></div>");
      }
      if (type === 'system') {
        $('#message_Box').append("<div class=\"system_msg\">" + umsg + "</div>");
      }

      $('#message').val(''); //reset text
    };

    websocket.onerror = function (ev) {
      $('#message_Box').append("<div class=\"system_error\">Error Occurred - " + ev.data + "</div>");
    };
    websocket.onclose = function (ev) {
      $('#message_Box').append("<div class=\"system_msg\">Connection Closed</div>");
    };
  });
</script>
<div class="chat_wrapper">
    <div class="message_Box" id="message_Box"></div>
    <div class="panel">
        <input type="text" name="name" id="name" placeholder="Your Name" maxlength="10" style="width:20%"/>
        <input type="text" name="message" id="message" placeholder="Message" maxlength="80" style="width:60%"/>
        <button id="send-btn">Send</button>
    </div>
</div>

</body>
</html>

有人知道为什么要在文件名上重复1或将其追加吗?或者只是如何解决此问题?预先感谢您的帮助!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)