Asegurar comandos

1

Para un proyecto en el que estoy trabajando, necesito enviar comandos de forma segura entre servidores. Estos comandos no deberían poder modificarse, y debería haber cierta seguridad acerca de no poder seguir reenviando la solicitud.

Esto es lo que he encontrado:

public static function encryptCommand($command) {
    $time = microtime(true);
    $command .= ':' . $time;
    $encryptedCommand = Security::encrypt($command, Configure::read('key'));
    $hash = Security::hash($time);

    return array(
        'command' => $encryptedCommand,
        'hash' => $hash
    );
}

public static function decryptCommand($data) {
    $encryptedCommand = $data['command'];
    $decryptedCommand = Security::decrypt($encryptedCommand, Configure::read('key'));

    $time = substr($decryptedCommand, strrpos($decryptedCommand, ':') + 1);

    if (Security::hash($time) != $data['hash']) {
        throw new SecurityException('The data has been tampered with.');
    }

    if (microtime(true) - $time > 5) {
        throw new SecurityException('Message arrived too late.');
    }

    return substr($decryptedCommand, 0, strrpos($decryptedCommand, ':'));
}

La idea es agregar la hora actual al comando, cifrarlo y enviarlo junto con un hash del tiempo. En el lado de recepción, puedo descifrar el comando, comparar el hash enviado con un nuevo cálculo del hash de tiempo en el comando descifrado, y verificar si no ha pasado demasiado tiempo.

¿Es este un buen enfoque, me estoy perdiendo algo? ¿Debo hacer esto de manera diferente?

    
pregunta nhaarman 07.10.2014 - 09:21
fuente

2 respuestas

3

Si alguien logra capturar una solicitud como esta, puede ser posible reenviar la solicitud varias veces en su marco de cinco segundos.

Ahora la pregunta es cómo prevenir esto. Hay más opciones, la más simple parece ser, que agregue una ID única a cada comando, y el servidor receptor los almacena de una manera (como una tabla) y ejecuta sus comandos solo si es la primera vez que es único. La identificación llega. De esta manera cada comando será ejecutado una sola vez. Además, puede usar el tiempo y almacenar las identificaciones únicas solo durante 24 horas, por lo que su mesa (o lo que sea) no es demasiado grande. En este caso, solo tiene que verificar si la marca de tiempo con el mensaje es de las últimas 24 horas y la ID única es única en las últimas 24 horas. De esta manera, tampoco tendrá problemas si los relojes de sus servidores no están en perfecta sincronización.

Editar

No sé cuántos servidores tiene, pero con este concepto parece que también es posible detectar una solicitud a un servidor y enviarla a todos los demás servidores. Si es así, debe agregar el nombre del servidor al que desea dar un comando.

    
respondido por el Tokk 07.10.2014 - 10:16
fuente
0

La forma más sencilla de prevenir los ataques de reproducción es asignar un número de serie único y creciente a cada comando (siempre en aumento) y hacer que el servidor recuerde cuál fue la última serie que recibió. Entonces rechazará cualquier serie nueva que no sea estrictamente más grande que la grabada anteriormente.

Es posible que deba mantener una lista de las últimas series vistas por fuente, a menos que tenga una manera de sincronizar estos números globalmente

    
respondido por el Stephane 07.10.2014 - 14:35
fuente

Lea otras preguntas en las etiquetas