Autenticación vía HMAC
El método de autenticación HMAC o Hash-based message authentication code (Código de autenticación de mensajes basado en hash), y la idea de esta autenticación se basa en 3 conceptos principales.
- Función de Hash, que sea difícil de romper y que sea conocida tanto por el cliente como el servidor.
- Palabra secreta, también es compartida por el cliente y el servidor.
- Datos que viajan de forma pública.
Cómo funciona
Lo que sucede es que el cliente sabiendo la función de hash y el secreto, toma esa información pública y con todo eso concatena y arma un mensaje que será enviado al servidor.
El servidor toma una información pública, el servidor ya conoce la información de hashing y el secreto, y vuelve a generar ese hash. Y luego, compara el recibido con el generado por el servidor, si coinciden la autenticación se produce, si no coinciden el servidor asume que ese usuario no está habilitado.
Para saber si ciertos encabezados estén en el array de encabezados que recibimos utilizamos HTTP_X_HASH, estos se suelen denotar con la letra X para decir que son encabezados no estándar.
!array_key_exists('HTTP_X_HASH')
- list() → Nos deja asignar variables como si fueran un array, no es realmente una función, es un constructor del lenguaje. Este se utiliza para asignar una lista de variables en una sola operación.
Para crear un autenticación HMAC tenemos que:
- Crear una condicional que si algunos de los encabezados no estándar que necesitamos no vienen datos por el cliente, muera el programa ahí.
- Hace una lista de variables que contengan los encabezados no estándar que necesitamos.
- Creamos una variable con nuestra palabra secreta
- Y una variable que contenga el hash, dentro de la variable hacemos una función hash pasándole los parámetros del ID del usuario, el timestamp y la palabra secreta
- Al final creamos otra condicional donde evaluamos si nuestro Hash no es igual al Hash que nos a dado el usuario. Si es verdad que no es igual, el programa termina en esa línea.
if (!array_key_exists('HTTP_X_HASH', $_SERVER) || !array_key_exists('HTTP_X_TIMESTAMP', $_SERVER) || !array_key_exists('HTTP_X_UID', $_SERVER) ) {
die;
}
list( $hash, $uid, $timestamp ) = [
$_SERVER['HTTP_X_HASH'],
$_SERVER['HTTP_X_UID'],
$_SERVER['HTTP_X_TIMESTAMP'],
];
$secret = 'Sh!! Es un secreto';
$newHash = sha1($uid . $timestamp . $secret);
if ( $newHash !== $hash) {
die;
}