2013-08-13 18 views
10

Sto provando a creare un server socket utilizzando stream_socket_server().Server socket PHP che utilizza ADH. Come?

Le connessioni normali funzionano correttamente, ma desidero creare un server che crittografa la connessione senza un certificato. So che questo può essere ottenuto con il codice ADH, e sì, so che è teoricamente meno sicuro che con un certificato ...

Il motivo per cui sto facendo questo server in primo luogo è quello di prendere in giro un server diverso a cui si connette un client (oltre this protocol, se vi state chiedendo).

Il client è configurato per richiedere prima un certificato e il backup su ADH: l'ho verificato con la realtà e si connette senza problemi, quindi il problema è con il server socket.

Tutto quello che ho provato fino ad ora ha provocato un errore di "handshake failure".

Alcune delle configurazioni che ho provato:

<?php 
$server = stream_socket_server(
     "tls://127.0.0.1:6667", 
     $errorno, 
     $errstr, 
     STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, 
     stream_context_create(
      array('ssl' => array('ciphers' => 'ADH')) 
     ) 
    ); 
?> 

<?php 
$server = stream_socket_server(
     "tls://127.0.0.1:6667", 
     $errorno, 
     $errstr, 
     STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, 
     stream_context_create(
      array('ssl' => array('ciphers' => '-COMPLEMENTOFALL ADH')) 
     ) 
    ); 
?> 

Ho anche cercato di regolare il client per utilizzare incondizionatamente ADH (come con il secondo esempio sopra), solo per amor di test, ma anche questo non riesce.

Questo succede con tutte le versioni di PHP che ho provato, l'ultima delle quali è la 5.5.0.

Qualche idea?

+0

vedere questo può essere sia di aiuto si http://christophh.net/2012/ 07/24/php-socket-programming/ – krishna

+0

@krishna Questo articolo non menziona nemmeno la crittografia, e dato che la connessione non crittografata funziona bene, non aiuta affatto. –

risposta

5

Vorrei utilizzare uno strumento come Wireshark per esaminare i bit sul filo in modo da poter determinare esattamente cosa non va nella stretta di mano. Senza questa abilità, stai volando (o eseguendo il debug) cieco.

Una volta che sai cosa non va nella tua stretta di mano, puoi capire il "perché".

+0

Per qualche motivo, Wireshark non acquisisce il traffico dal mio computer a se stesso. Questo è anche quando sostituisco "127.0.0.1" con l'IP (pubblico) del mio computer. Cercherò di configurare un computer secondario e vedere se questo fa il trucco ... –

+0

I byte grezzi possono essere visti qui https://gist.github.com/boenrobot/6331636 Per quanto riguarda la decodifica di Wireshark questo - il pacchetto Hello contiene solo cifrari ADH (come previsto per questo particolare test) e il server risponde con "handshake failure (40)". –

+0

Oh, e sul client, viene visualizzato il seguente messaggio di errore: "errore: 14094410: routine SSL: SSL3_READ_BYTES: errore di handshake di avviso sslv3". (dispari...Sto usando TLS su entrambi i peer, non su SSLv3) –

1

Verificare innanzitutto che SSL sia configurato correttamente nel server? Run SSL Scanner al servizio. Ho uno script di test che non funziona affatto, poiché le chiamate OpenSSL non vengono eseguite senza un file chiave. Questa non è una risposta, ma mi manca tempo per ulteriori indagini ...

Sei consapevole che ADH è una crittografia debole? ~ la maggior parte degli avvisi di sicurezza consiglia di disattivarla. lettura generale sulle ADH http://wiki.openssl.org/index.php/Manual:Ciphers(1)

+0

Sì. Come ho detto all'inizio, sono consapevole che ADH è meno sicuro di una connessione con un certificato e sto provando a creare un server come un mock in un test di unità, non per l'uso "di produzione". Il vero server supporta ADH come alternativa quando il server non ha alcun certificato. Per quanto riguarda SSLScan ... ho eseguito [la porta Windows di SSLScan] (http://code.google.com/p/sslscan-win/), e dopo aver modificato leggermente lo script in stream_socket_accept() anche in caso di errore, I vedi tutti i cifrari come "Rifiutati" con il server che restituisce lo stesso pacchetto esattamente come notato in precedenza. –

+0

BTW, cosa interessante da notare ... con il server di test come sopra, ottengo solo i cifrari TLSv1 e SSLv3 come "Rifiutato" e SSLv2 come "Non riuscito". Quando inserisco un file vuoto come opzione di contesto "local_cert", ottengo anche i cifrari SSLv2 come "Rifiutati". –

+0

cert locale vuoto ... me lo aspetterei. Poiché questo è scritto da un punto di vista della sicurezza; un file vuoto è uguale a un certificato non valido che rifiuta tutti. –

1

vedere questo può aiutare a

<?php 
// PHP SOCKET SERVER 
error_reporting(E_ERROR); 
// Configuration variables 
$host = "127.0.0.1"; 
$port = 4041; 
$max = 20; 
$client = array(); 

// No timeouts, flush content immediatly 
set_time_limit(0); 
ob_implicit_flush(); 

// Server functions 
function rLog($msg){ 
      $msg = "[".date('Y-m-d H:i:s')."] ".$msg; 
      print($msg."\n"); 

} 
// Create socket 
$sock = socket_create(AF_INET,SOCK_STREAM,0) or die("[".date('Y-m-d H:i:s')."] Could not create socket\n"); 
// Bind to socket 
socket_bind($sock,$host,$port) or die("[".date('Y-m-d H:i:s')."] Could not bind to socket\n"); 
// Start listening 
socket_listen($sock) or die("[".date('Y-m-d H:i:s')."] Could not set up socket listener\n"); 

rLog("Server started at ".$host.":".$port); 
// Server loop 
while(true){ 
      socket_set_block($sock); 
      // Setup clients listen socket for reading 
      $read[0] = $sock; 
      for($i = 0;$i<$max;$i++){ 
          if($client[$i]['sock'] != null) 
             $read[$i+1] = $client[$i]['sock']; 
      } 
      // Set up a blocking call to socket_select() 
      $ready = socket_select($read,$write = NULL, $except = NULL, $tv_sec = NULL); 
      // If a new connection is being made add it to the clients array 
      if(in_array($sock,$read)){ 
          for($i = 0;$i<$max;$i++){ 
             if($client[$i]['sock']==null){ 
                if(($client[$i]['sock'] = socket_accept($sock))<0){ 
                   rLog("socket_accept() failed: ".socket_strerror($client[$i]['sock'])); 
                }else{ 
                   rLog("Client #".$i." connected"); 
                } 
                break; 
             }elseif($i == $max - 1){ 
                rLog("Too many clients"); 
             } 
          } 
          if(--$ready <= 0) 
          continue; 
      } 
      for($i=0;$i<$max;$i++){ 
          if(in_array($client[$i]['sock'],$read)){ 
             $input = socket_read($client[$i]['sock'],1024); 
             if($input==null){ 
                unset($client[$i]); 
             } 
             $n = trim($input); 
             $com = split(" ",$n); 
             if($n=="EXIT"){ 
                if($client[$i]['sock']!=null){ 
                   // Disconnect requested 
                   socket_close($client[$i]['sock']); 
                   unset($client[$i]['sock']); 
                   rLog("Disconnected(2) client #".$i); 
                   for($p=0;$p<count($client);$p++){ 
                       socket_write($client[$p]['sock'],"DISC ".$i.chr(0)); 
                   } 
                   if($i == $adm){ 
                       $adm = -1; 
                   } 
                } 
             }elseif($n=="TERM"){ 
                // Server termination requested 
                socket_close($sock); 
                rLog("Terminated server (requested by client #".$i.")"); 
                exit(); 
             }elseif($input){ 
                // Strip whitespaces and write back to user 
                // Respond to commands 
                /*$output = ereg_replace("[ \t\n\r]","",$input).chr(0); 
                socket_write($client[$i]['sock'],$output);*/ 
                if($n=="PING"){ 
                   socket_write($client[$i]['sock'],"PONG".chr(0)); 
                } 
                if($n=="<policy-file-request/>"){ 
                   rLog("Client #".$i." requested a policy file..."); 
                   $cdmp="<?xml version=\"1.0\" encoding=\"UTF-8\"?><cross-domain-policy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://www.adobe.com/xml/schemas/PolicyFileSocket.xsd\"><allow-access-from domain=\"*\" to-ports=\"*\" secure=\"false\" /><site-control permitted-cross-domain-policies=\"master-only\" /></cross-domain-policy>"; 
                   socket_write($client[$i]['sock'],$cdmp.chr(0)); 
                   socket_close($client[$i]['sock']); 
                   unset($client[$i]); 
                   $cdmp=""; 
                } 
             } 
          }else{ 
             //if($client[$i]['sock']!=null){ 
                // Close the socket 
                //socket_close($client[$i]['sock']); 
                //unset($client[$i]); 
                //rLog("Disconnected(1) client #".$i); 
             //} 
          } 
      } 
} 
// Close the master sockets 
socket_close($sock); 
?> 

per più see this e vedere questo anche per more

+0

Grazie per aver cercato di aiutare, ma questo codice - così come entrambi gli articoli a cui si collega - non riguardano affatto la crittografia, che è la parte problematica dell'intera domanda. Le connessioni non crittografate funzionano bene, anche senza l'estensione socket. L'unica menzione della crittografia nell'intera cosa è un paragrafo nell'articolo di Zend che non si riferisce nemmeno a TLS di per sé, e non ha nemmeno un esempio di base per la menzionata Mcrypt. –