¿Estos métodos criptográficos van por el camino correcto?

2

Sé que nunca debemos "rodar nuestro propio criptografía", pero quiero entender el funcionamiento interno. He escrito las siguientes dos funciones de cifrado / descifrado en PHP:

function encrypt($message) {

    $key = hash("sha256", base64_decode($secretpw64));    // get key from secret password
    $iv = random_bytes(16);                               // create an iv
    $output = openssl_encrypt($message, "AES-256-CBC", $key, 0, $iv);    // encrypt using openssl

    return implode(".", array(base64_encode($iv), $output));             // join iv.output
}

function decrypt($message) {

    $key = hash("sha256", base64_decode($secretpw64));    // get key from secret password
    $segs = explode(".", $message);    // separate the message
    $iv = base64_decode($segs[0]);     // get the iv
    $emsg = $segs[1];                  // get the encrypted message

    return openssl_decrypt($emsg, "AES-256-CBC", $key, 0, $iv);    // decrypt and return
}

Supongo (lo que sé que no debería) que random_bytes produce un conjunto de bytes aleatorios y criptográficos seguros, que de acuerdo con la documentación. También utilizo un Vector de inicialización ( iv ) que hace que el cifrado sea diferente cada vez que se proporciona la misma entrada.

¿Es este código fundamentalmente defectuoso desde el punto de vista de la seguridad de alguna manera? Y, suponiendo que no lo es entonces es hash-then-encrypt (o similar) el siguiente" subir de nivel "?

    
pregunta Antinous 26.04.2018 - 14:15
fuente

1 respuesta

2

Hay algunos problemas con tu código.

$key = hash("sha256", base64_decode($secretpw64));

SHA-256 es muy rápido, y aquí no hay sal. Un atacante puede crear un diccionario de (secretpw64, clave) y obtener la clave mediante un ataque de diccionario rápido y sucio. Como han dicho otros, considere usar un PBKDF. Incluso iterar el SHA para, digamos, 1000 veces puede estar bien. Para obtener más información sobre cómo obtener una clave criptográfica a partir de una contraseña, vea esta respuesta en Crypto.SE .

 $iv = random_bytes(16); 

Está asumiendo que random_bytes es un PRNG criptográficamente seguro, pero esto no es algo que pueda hacer con la mano. ¡Ten cuidado!

Por otra parte, eche un vistazo a cómo se generan los IV.

Si la aplicación falla, o si cierra el sistema operativo y comienza de nuevo, ¿el primer IV es siempre el mismo? Podría ocurrir.

Si lo hace, un atacante puede bloquear la aplicación y obtener dos mensajes con la misma clave y IV cuando quiera . ¡No hay necesidad de esperar 2 ^ 64 mensajes!

La confidencialidad no es todo en seguridad. La integridad y la autenticación de mensajes también son importantes en la mayoría de las aplicaciones.

Resulta que, CBC también es vulnerable a ataques de cambio de bits (también conocido como cambio de bytes).

Básicamente, puede voltear un byte en el texto cifrado para voltear un byte correspondiente en el texto plano. Esto normalmente codifica el bloque anterior, pero se convierte en un ataque práctico cuando desea modificar el primer bloque y puede cambiar el IV o, en algunos casos, omitiendo la validación de entrada. Para obtener más información, consulte este resumen de Defcamp .

Finalmente, también debe considerar otros ataques no criptoanalíticos, dependiendo de su modelo de amenaza, incluyendo:

  • robo / divulgación de claves de cifrado (por ejemplo, desde la RAM);
  • modificaciones maliciosas o secuestro del RNG. Si, por ejemplo, un atacante puede reemplazar su RNG con un PRNG débil, todo se rompe.
respondido por el A. Darwin 26.04.2018 - 20:34
fuente

Lea otras preguntas en las etiquetas