【问题标题】:PHP stream socket not decrypting dataPHP流套接字不解密数据
【发布时间】:2016-03-08 15:19:41
【问题描述】:

我正在尝试建立一个安全的 websocket 连接,但是我的数据似乎没有被解密。尝试了几种读取数据的方法,但都不起作用。

有人知道是什么原因造成的吗?

我的套接字服务器

//Create the main socket
$context = stream_context_create();

// local_cert must be in PEM format
stream_context_set_option($context, 'ssl', 'local_cert', '/storage/chat/Jongeren.pem');
stream_context_set_option($context, 'ssl', 'passphrase', '*****');

// Create the server socket
$this->master = stream_socket_server(
        "tls://$addr:$port",
        $errno,
        $errstr,
        STREAM_SERVER_BIND|STREAM_SERVER_LISTEN,
        $context
);
stream_set_blocking($this->master, 0);
$this->Sockets['master'] = $this->master;

if($errno > 0){ //An error has occured
    log::debug("Main socket error ($errno): $errstr");
    die();
} else {
    log::info("Main socket started, listening on $addr:$port");
}

while(true) {
  //Select sockets witch activity
  $read = $this->Sockets;
  $changed = stream_select($read,$write,$except,1);

    //Process changed
    if( (false !== $changed) && ($changed > 0) ){

        //Accept new connections
        if( in_array($this->master, $read) ){
            $new_client = stream_socket_accept($this->master, 1, $remote_host);
            if ($new_client) {              
                $index = uniqid();
        $this->Sockets[$index] = $new_client;
        $this->users[$index] = new $this->userClass($remote_host);
        $this->ConnectionSettings[$index] = new Connection();
        log::info('incoming connection: '.$remote_host);
        log::info('client count: '. (count($this->Sockets)-1) );
      } else {
                $err = socket_last_error($socket);
        log::debug("Socket error: ".$err.": ".socket_strerror($err), NULL,NULL);
            }
        }

        //delete the server socket from the read sockets
    unset($read['master'], $new_client, $remote_host);

    //Process changed sockets
    foreach ($read as $socket) {

             if( false !== ($buffer = stream_socket_recvfrom($socket,8192) ) ){
                $sID = $this->getSocketID($socket);
                if( empty( $buffer ) ){
                    $this->disconnect($sID, false);
                } else {
                    log::info( 'Data: '.$buffer );
                }
            }
    }
  }
}

数据输出:

2015-12-03T21:35:46+01:00 >> Main socket started, listening on 192.168.1.100:9090
2015-12-03T21:35:51+01:00 >> incoming connection: 192.168.1.1:43022
2015-12-03T21:35:51+01:00 >> client count: 1
2015-12-03T21:35:51+01:00 >> Data: lw���ٮ(0�����MO��gyp��³sy��,b7��>��-�F�}ǮsF'g�EMg�c8�
                                                                                                     �F
 �z�F�k{    5�dP�IQ�+��ڞ���~�Q������h5v��Z��FEɸ�� .�~�͉���ªgf\=���Y>�2�
H�_��E�qS��� ����I��.�W
                        /�V �
�Z\���
�u���o�����"�V�)J[���;>�O��y���3?��,��'Ğ-�y�3ݱ1qid�;He�2o�(wyo��C����rt��{[K%�U2�'����"�_�ζA���m
                                                                                                     7�4* ���4ؑ����_���Y�7RO�˝�}J�t���Д�Iݼ`�&KƉ�pƫ,�x�
                                                   �l'~/���NL,��@��<ݿ�U{��'�7r5��w��X�|Va�~f���^���R��5��������Y�K0��.QN�c'�p{-c��߼y�{��Ыr���:ZʬH͞$\�Tl��SQ��*��[���7|#
                                                                               S0�����F���Sh)bL3&�E
      ���czE��J�#��Q.��Q    �����'�E

【问题讨论】:

  • 对此不熟悉,但您将ssl 指定为stream_context_set_option() 中的包装器,然后调用tls:// URL。您是否尝试将两者都设置为tls?第二个想法:你需要运行stream_socket_enable_crypto()吗?我想tls:// URL 会自动执行此操作,但不确定。
  • @miken32:尝试了stream_socket_enable_crypto(),但得到了响应,它已经为套接字启用了。 ssl:// 和 tls:// 都给出相同的结果
  • php.net/manual/en/function.stream-socket-recvfrom.php 说 fread 应该提供解密的数据。我试过了,但没有用。明天再试一次。
  • 更新:fread 给出相同的结果
  • 刚刚遇到这个(我目前正在自己​​做一些套接字编程,但没有加密)示例代码有帮助吗?它使用tcp:// 包装器打开流,然后启用加密。 stackoverflow.com/a/22003476/1255289

标签: php sockets ssl encryption


【解决方案1】:

我终于解决了。

//Create the main socket
$context = stream_context_create();

// local_cert must be in PEM format
stream_context_set_option($context, 'ssl', 'local_cert', 'file.pem');
stream_context_set_option($context, 'ssl', 'passphrase', '***');
stream_context_set_option($context, 'ssl', 'allow_self_signed', true);
stream_context_set_option($context, 'ssl', 'verify_peer', false);

// Create the server socket
$this->master = stream_socket_server(
            "ssl://$addr:$port",
            $errno,
            $errstr,
            STREAM_SERVER_BIND|STREAM_SERVER_LISTEN,
            $context
    );

$this->Sockets['master'] = $this->master;

if($errno > 0){ //An error has occured
  log::debug("Main socket error ($errno): $errstr");
  die();
} else {
  log::info("Main socket started, listening on $addr:$port");
}

while(true) {

  //Select sockets witch activity
  $read = $this->Sockets;
  stream_select($read,$write,$except,60);

  if(count($read) > 0){
$t = count($this->Sockets)-1;
$r = count($read);
$w = count($write);
$e = count($except);
log::info( 'T:'.$t.' R:'.$r.' W:'.$w.' E:'.$e );
  }

  //Accept new connections
  if( in_array($this->master, $read) ){
$new_client = stream_socket_accept($this->master, 1, $remote_host);
    if ($new_client) {
    $index = uniqid();
    $this->Sockets[$index] = $new_client;
        $this->users[$index] = new $this->userClass($remote_host);
        $this->ConnectionSettings[$index] = new Connection();
        log::info('Accepted connection: '.$remote_host);
    } else {
        $err = socket_last_error($socket);
        log::debug("Socket error: ".$err.": ".socket_strerror($err), NULL,NULL);
    }
  }

  //delete the server socket from the read sockets
  unset($read['master'], $new_client, $remote_host );

  //Process changed sockets
  foreach ($read as $socket) {
$buffer = fread($socket, 2046);

    $sID = $this->getSocketID($socket);
if( empty( $buffer ) ){
  $this->disconnect($sID, false);
} else {
  log::info( 'Data: '.$buffer );
  if (!$this->ConnectionSettings[$sID]->shake) {  //HANDSHAKE
    $this->doHandshake($sID,$buffer);
      } else if ($message = $this->deframe($sID, $buffer)) { //MESSAGE
    $this->process($sID, utf8_encode($message));
  }
}
  }
  //cleanup
  unset($read,$r,$write,$w,$except,$e,$socket,$buffer);
}

问题是我没有使用正确的证书。我是多么愚蠢:(

所以这些事情很重要:

  • 使用与 IP 地址或域的证书一致的正确连接字符串
  • 在pem文件中按此顺序拥有私钥、证书、中间体、CA。
  • 使用 fread 和 frwrite 进行通信

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-11
    • 2012-04-03
    • 2019-10-10
    • 1970-01-01
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多