¿PHP OpenSSL es más seguro que solo usar MySQL AES_ENCRYPT / DECRYPT solo?

2

Deseo cifrar / descifrar datos en mi base de datos MySQL almacenada en mi servidor. Yo uso un hash salado para mis contraseñas. Todo el cifrado / descifrado se produciría en el servidor. Utilizo los puntos finales de PHP a los que acceden mis clientes remotos. Los puntos finales luego acceden a la base de datos MySQL.

Tengo el siguiente código PHP para cifrar / descifrar un mensaje:

<?php
    $key = "mySecretKey";
    $cipher = "aes-128-gcm";
    $ivlen = openssl_cipher_iv_length($cipher);

    $iv = openssl_random_pseudo_bytes($ivlen);
    $ciphertext = openssl_encrypt("message to be encrypted", $cipher, $key,     $options=0, $iv, $tag);

    $original_plaintext = openssl_decrypt($ciphertext, $cipher, $key, 0, $iv, $tag);

    echo "original message: ".$original_plaintext."\n";

    // $iv and $tag change each time we encrypt the data, so store these
?>

... que iba a utilizar para almacenar datos cifrados en mi base de datos. Sin embargo, también necesitaré almacenar $iv y $tag con mis datos, ya que estos cambios para cada openssl_encrypt ejecutado.

Por otro lado, podría usar las funciones AES_ENCRYPT de MySQL. Esta opción simplificaría mucho mi código, porque solo puedo agregar AES_ENCRYPT(data, key) a mi código SQL.

Sin embargo, tengo la sensación de que la solución PHP es más segura que solo AES_ENCRYPT . ¿Es esto cierto?

Por otro lado, no estoy tan seguro. Por ejemplo, si alguien se apoderó de mi clave AES_ENCRYPT , entonces también podría apoderarse de mi% $key en PHP, en cuyo caso también podrían descifrar el mensaje openssl_encrypt -ed messge, ya que% La información de $iv$ y $tag probablemente sería tan fácil de obtener si tienen en sus manos el $key de alguna manera.

O tal vez me dirijo a mi solución de PHP por el camino equivocado. ¿Tal vez no se debe generar $iv cada vez que encripta una información? Tal vez $iv debería ser final, es decir, siempre el mismo, en cuyo caso $tag siempre es el mismo ...

    
pregunta Antinous 24.04.2018 - 12:26
fuente

2 respuestas

3

Si hiciera el cifrado en el lado del servidor MySQL, tendría que enviar los datos (sin cifrar) al servidor MySQL. Para hacer esto de manera segura, necesitaría asegurar una conexión encriptada al servidor MySQL para proteger los datos en tránsito. Dependiendo de su configuración, los datos podrían (parcialmente) terminar en un archivo de registro en alguna parte. Todo esto agrega una capa de complejidad, sin beneficio adicional de seguridad.

Lea también: Es "¿Por qué debería evitarlo? AES en MySQL? "True? .


Cifrar en el lado de PHP
Si cifra los datos en el lado de PHP, puede hacer uso de paquetes fáciles de usar ( SymmetricEncryption o php-encryption viene a la mente), y simplemente almacene la cadena cifrada en su base de datos, que es mucho menos compleja.
Teniendo en cuenta su pregunta sobre, por ejemplo, el requisito de $iv , le recomiendo que use una biblioteca estándar.

Entonces, en resumen: Sí, usar PHP OpenSSL es más seguro que MySQL AES_ENCODE / DECODE.

    
respondido por el Jacco 24.04.2018 - 12:40
fuente
2

No use AES_ENCRYPT a menos que entienda completamente problemas y cómo usarlo correctamente!

Hay varios problemas importantes con AES_ENCRYPT:

Tiene valores por defecto pobres

El block_encryption_mode predeterminado es aes-128-ecb . Cualquier persona que entienda qué es ecb y lo vea aquí como un valor predeterminado, probablemente esté temblando ahora mismo. Basta con decir que puede filtrar una cantidad significativa de información .

Recomienda una derivación de clave insegura

De la documentación :

  

Se puede usar una frase de contraseña para generar una clave AES mediante la   frase de contraseña Por ejemplo:

INSERT INTO t
VALUES (1,AES_ENCRYPT('text', UNHEX(SHA2('My secret passphrase',512))));
     

No pasar una contraseña o frase de contraseña directamente a crypt_str, hash it   primero. Las versiones anteriores de esta documentación sugirieron la primera   enfoque, pero ya no se recomienda como los ejemplos que se muestran aquí   Son más seguros.

¡Aparentemente recomendaron usar una contraseña directamente como clave! Ahora lo han mejorado a una sola iteración de una función hash rápida sin sal. Para saber por qué esto sigue siendo bastante terrible, consulte aquí . El método correcto sería utilizar una función de derivación de clave basada en contraseña, como PBKDF2.

No admite el cifrado autenticado

Los modos admitidos son ECB, CBC, CFB1 , CFB8, CFB128, OFB. La mayoría de estos modos son maleables hasta cierto punto, y algunos de ellos le permiten voltear un bit específico en el texto cifrado para voltear el mismo bit en el texto plano. Su pregunta sugiere que estaría usando GCM, lo que evita esto al verificar la autenticidad.

Incluso si no quisiera un cifrado autenticado, personalmente preferiría evitar el uso de valores predeterminados y recomendaciones tan inseguros, y como Jacco señala , el cifrado en PHP es mejor si no puede garantizar que la conexión entre PHP y MySQL use TLS.

    
respondido por el AndrolGenhald 24.04.2018 - 16:30
fuente

Lea otras preguntas en las etiquetas