For a project I'm working on, I need to securely send commands between servers. These commands should not be able to be altered, and there should be some security about not being able to just keep resending the request.
This is what I've come up with:
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, ':'));
}
The idea is to append the current time to the command, encrypt it, and send it together with a hash of the time. At the receiving side, I can decrypt the command, compare the sent hash with a new calculation of the time hash in the decrypted command, and check if not too much time has passed.
Is this a good approach, am I missing something? Should I do this differently?