Protezione dei comandi

1

Per un progetto su cui sto lavorando, ho bisogno di inviare comandi in modo sicuro tra i server. Questi comandi non dovrebbero essere alterati e ci dovrebbe essere un po 'di sicurezza per non essere in grado di continuare a inviare nuovamente la richiesta.

Questo è quello che mi è venuto in mente:

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, ':'));
}

L'idea è di aggiungere l'ora corrente al comando, crittografarlo e inviarlo insieme con un hash del tempo. Dal lato ricevente, posso decodificare il comando, confrontare l'hash inviato con un nuovo calcolo dell'hash tempo nel comando decrittografato e controllare se non è passato troppo tempo.

È un buon approccio, mi manchi qualcosa? Dovrei farlo diversamente?

    
posta nhaarman 07.10.2014 - 09:21
fonte

2 risposte

3

Se qualcuno riesce a prendere una richiesta come questa potrebbe essere possibile inviare nuovamente la richiesta numerose volte nel tuo frame di cinque secondi.

Ora la domanda è come prevenirlo. Ci sono più opzioni, la più semplice sembra essere, che si aggiunge un ID univoco a ciascun comando, e il server di ricezione le memorizza in un modo (come una tabella) ed esegue i comandi solo se è la prima volta che questo è unico ID arriva. In questo modo ogni comando verrà eseguito una sola volta. Puoi inoltre utilizzare l'ora e archiviare gli ID univoci solo per 24 ore, in modo che la tua tabella (o qualsiasi altra cosa) non diventi troppo grande. In questo caso, devi solo verificare se il timestamp con il messaggio è degli ultimi 24 ore e l'ID univoco è unico nelle ultime 24 ore. In questo modo non avrai problemi se i clock dei tuoi server non sono perfettamente sincronizzati.

Modifica

Non so quanti server hai ma con questo concetto sembra che sia anche possibile prendere una richiesta su un server e inviarla a tutti gli altri server. In tal caso, è necessario aggiungere il nome del server a cui si desidera dare un comando.

    
risposta data 07.10.2014 - 10:16
fonte
0

Il modo più semplice per prevenire gli attacchi di riproduzione consiste nell'assegnare un numero di serie univoco e crescente a ciascun comando (sempre crescente) e fare in modo che il server ricordi quale sia stato l'ultimo seriale ricevuto. Quindi rifiuterà qualsiasi nuovo serial che non sia strettamente più grande di quello precedentemente registrato.

Potrebbe essere necessario mantenere un elenco degli ultimi serial visti per fonte, a meno che non si abbia un modo per sincronizzare questi numeri globalmente

    
risposta data 07.10.2014 - 14:35
fonte

Leggi altre domande sui tag