¿Es este un esquema válido de cookies seguras?

3

Tengo un esquema para una cookie con alto nivel de confidencialidad de la información. La información que se debe ocultar al cliente es el tiempo de caducidad de la cookie. Me pregunto a qué inseguridades me estoy abriendo con este esquema.

Note a continuación que | denota concatenación y (text)k es texto cifrado usando la clave k.

cookie = creation_time | (expiration_time)k | HMAC(creation_time|expiration_time|server_key , k) where k = HMAC(creation_time, server_key)

Los pasos para la validación de claves son:

  1. Asegúrate de que creation_time sea una marca de tiempo válida
  2. crear k = HMAC (creation_time, server_key)
  3. descifrar (expiration_time) k usando k.
  4. asegurar (expiration_time - creation_time <= T) & & current_time < expiration_time donde T es un servidor permitido TTL para una cookie.
  5. calcular HMAC (creation_time | expiration_time | server_key, k) y comparar con el valor de la cookie. Si son iguales la cookie es válida.

El punto central de esta cookie es permitirme garantizar que el usuario reciba una cookie en un punto y haga ping a través de ajax en un tiempo T .

    
pregunta lluisrojass 18.08.2017 - 21:39
fuente

1 respuesta

1

Hay algunas cosas mal con esta construcción.

No definiste qué algoritmo de cifrado estás usando. Si utilizara un modo de cifrado de bloque con relleno, como CBC, su diseño sería potencialmente vulnerable a un ataque de relleno de Oracle, ya que su servidor debe descifrar el valor expiration_time encriptado antes de validar el registro de autenticidad con el texto sin formato. Debe aplicar las comprobaciones de autenticidad contra el texto cifrado siempre que sea posible.

Tampoco está claro cómo funcionan los delimitadores entre campos. Debe definir cómo cada campo individual se produce por separado para evitar cualquier confusión en el proceso de decodificación.

Aunque no es crítico, también es una mala práctica tener una sola clave compartida para el cifrado / descifrado y la autenticidad (HMAC). Siempre debe intentar tener claves independientes para estos.

Todo en todo esto es un diseño demasiado complejo.

Una forma más sencilla es simplemente almacenar el tiempo de caducidad como una variable de sesión, como esta en PHP:

session_start();
$_SESSION['expiry'] = time() + 60 * 60 * 24; // now +24 hours

Y luego en cada solicitud:

session_start();
if (!isset($_SESSION['expiry']) || !is_int($_SESSION['expiry']))
{
    // expiry time has been unset or corrupted somewhere, log and fail
}
if ($_SESSION['expiry'] < time())
{
    // session expired, do whatever you need to do about this
}

Esto guarda el complejo esquema criptográfico y el acceso del lado del cliente al token.

    
respondido por el Polynomial 18.08.2017 - 22:28
fuente

Lea otras preguntas en las etiquetas