¿Este proceso de cifrado de datos es seguro?

2

He creado el siguiente proceso de cifrado que utilizaré para almacenar las claves de CD dentro de mi base de datos. Sin embargo, antes de usarlo, debo asegurarme de que sea lo más seguro posible.

Por lo que veo, hay dos preocupaciones principales:

  • El almacenamiento de la clave privada debe ser extremadamente seguro. Si alguien obtiene una retención de la clave principal, puede descifrar todos los datos de mi base de datos

  • El método de encriptación debe ser lo más seguro posible

¿Hay una mejor manera de almacenar datos de forma segura en este escenario? Si no, ¿cómo puedo asegurarme de que este proceso sea lo más seguro posible?

Aquí está mi código:

public static function encrypt_key($key)
{
        $iv_size = mcrypt_get_iv_size(MCRYPT_CAST_256, MCRYPT_MODE_CBC);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        return $iv . openssl_encrypt ($key, 'AES-256-CBC', '32 bit private key', 0, $iv);
}

public static function decrypt_key($key)
{
        $iv_size = mcrypt_get_iv_size(MCRYPT_CAST_256, MCRYPT_MODE_CBC);
        $iv = substr($key, 0, $iv_size);
        return openssl_decrypt(substr($key, $iv_size), 'AES-256-CBC', '32 bit private key', 0, $iv);
}
    
pregunta dspacejs 19.07.2015 - 11:27
fuente

1 respuesta

3

Se pueden realizar varias mejoras a las funciones que ha asignado, según mi conocimiento.

Amenazas obvias

Primero, y lo más importante, mantenga segura su clave privada , y haga que sea externa a la definición de la función (por ejemplo, un segundo argumento). Recomendaría hacer un esfuerzo significativo para resolver este problema. ¿Es este cifrado por usuario o el cifrado de toda la aplicación? Si es por usuario, ¿por qué no usar un algoritmo de derivación de claves, como PBKDF2 ? Si es de toda la aplicación, buena suerte con el almacenamiento seguro: lo he pensado antes y no parece trivial para una aplicación web típica. Solo asegúrese de que no almacene la clave privada junto con la fuente, ni (obviamente) en la misma base de datos .

Además, aparte, nunca uses cifrado simétrico para nada que sea como una contraseña. Utilice un hash unidireccional en su lugar. Supongo, para esta respuesta, que realmente necesitas recuperar la clave del CD original, en lugar de solo verificar una coincidencia.

Segundo, tengo dudas sobre el uso de MCRYPT_RAND. Parece que podría ser el mismo PRNG que rand () , que no es ideal. Generar el IV con MCRYPT_DEV_URANDOM es lo que recomendaría: / dev / random y / dev / urandom se consideran fuentes de primera clase de números aleatorios criptográficos en sistemas basados en Unix. Tenga en cuenta que no generalmente desea usar / dev / random para una aplicación web, ya que abriría un vector DoS fácil - y / dev / urandom debería ser suficiente fuera de los entornos integrados, de todos modos.

Otros problemas de implementación

Ahora, con las principales vulnerabilidades que puedo detectar, algunos detalles más detallados:

Estás mezclando las funciones OpenSSL y mcrypt. Además, openssl_encrypt no está documentado en los documentos oficiales de PHP (aunque sospecho que está documentado para C en algún lugar, sin embargo ...). Podría ser mejor usar mcrypt_encrypt , ya que está documentado explícitamente para PHP.

También estás mezclando CAST-256 y AES-256. Probablemente debería quedarse con AES-256 en todo momento, ya que ese es el algoritmo estándar generalmente recomendado para un cifrado simétrico sólido. Tenga en cuenta que AES-256 es MCRYPT_RIJNDAEL_128 utilizado con una clave de 256 bits , y NO es lo mismo que Rijndael-256, que es algo que no me había dado cuenta (¡cuanto más sabes!).

No estoy seguro de cuál es el modo de cifrado preferido, pero al menos CBC es uno que he visto recomendado para AES. Esperemos que alguien más tenga alguna entrada.

    
respondido por el Ethan Kaminski 19.07.2015 - 14:22
fuente

Lea otras preguntas en las etiquetas