Underc0de

[In]Seguridad Informática => Seguridad web y en servidores => Mensaje iniciado por: Dedalo en Octubre 19, 2014, 04:01:34 PM

Título: Uso seguro de AES ENCRYPT en MySQL
Publicado por: Dedalo en Octubre 19, 2014, 04:01:34 PM
(http://2.bp.blogspot.com/-s_JpurhCqM0/U5flTW51N_I/AAAAAAAAAvQ/8AqVQvNgRJo/s1600/mysql-aes.png)
Después de un tiempo sin escribir el buen clima hizo que mi perspectiva y mente se abrieran como para escribir un post interesante sobre una función de cifrado que tiene mysql. La función de la cual hablaré es AES_ENCRYPT();.

Primero, para desasnarnos un poco. ¿Qué es AES?.

AES es un algoritmo de cifrado simétrico (que depende de una password para descifrar), está calificado como un cifrado muy seguro. Mayor información sobre el cifrado googleen, por ahora me dedicaré a explicar cual el problema que hay con mysql.

Para cifrar información directo con la función de mysql debemos especificar lo que queremos cifrar y la contraseña para cifrar/descifrar. Esto se realiza de la siguiente manera.

Código (mysql) [Seleccionar]
mysql> SELECT HEX(AES_ENCRYPT('textoquequierocifrar', 'password'));
+------------------------------------------------------------------+
| HEX(AES_ENCRYPT('textoquequierocifrar', 'password'))             |
+------------------------------------------------------------------+
| 3FBC9CB7DE3881CB47A2007AF57B94C3849648881F12E3B49A23D83CF5842A9A |
+------------------------------------------------------------------+
1 row in set (0,02 sec)


Entonces, como pueden ver, nos devuelve el hex del AES de lo que hemos cifrado con la contraseña "password".

¿Dónde recae el "error" de esto? Por defecto Mysql no pone 256 bits al cifrado. Lo deja en 128 bits por lo que no es lo estandarizado para que el uso de AES sea completamente seguro. Haremos la consulta a la variable del sistema block_encryption_mode.

Código (mysql) [Seleccionar]
mysql> SELECT @@session.block_encryption_mode;
+---------------------------------+
| @@session.block_encryption_mode |
+---------------------------------+
| aes-128-ecb                     |
+---------------------------------+
1 row in set (0,00 sec)


Aquí se muestra lo que digo, se está usando AES-128-ECB -> AES es el cifrado 128 los bits y ECB el modo de operación. Esta información se puede corroborar en la página oficial de developers de mysql donde se documenta el uso de esta variable del sistema puedes dar click aquí (https://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_block_encryption_mode).

Para cambiarla a la de 256 solo debemos ejecutar la siguiente consulta -> SET @@session.block_encryption_mode = 'aes-256-ecb';

Una vez realizada la consulta pueden volver a hacer un select de block_encryption_mode y el resultado será diferente:

Código (mysql) [Seleccionar]
mysql> SELECT @@session.block_encryption_mode;
+---------------------------------+
| @@session.block_encryption_mode |
+---------------------------------+
| aes-256-ecb                     |
+---------------------------------+
1 row in set (0,00 sec)


Entonces, ahora, si ciframos un contenido se cifrará con un estándar realmente seguro. Cifraré lo mismo y veremos como cambia el resultado.

Código (mysql) [Seleccionar]
mysql> SELECT HEX(AES_ENCRYPT('textoquequierocifrar', 'password'));
+------------------------------------------------------------------+
| HEX(AES_ENCRYPT('textoquequierocifrar', 'password'))             |
+------------------------------------------------------------------+
| 6D9E4A37311B9A9FAB28BB183020341FADB51A99E038F22213B44876F88FD15A |
+------------------------------------------------------------------+
1 row in set (0,00 sec)


Si nos fijamos el hash que nos dio en el primer ejemplo con el de ahora son diferentes porque el cifrado fue fortalecido.

Primer Resultado:
3FBC9CB7DE3881CB47A2007AF57B94C3849648881F12E3B49A23D83CF5842A9A

Segundo Resultado:
6D9E4A37311B9A9FAB28BB183020341FADB51A99E038F22213B44876F88FD15A

Para decifrar estos hashes es muy simple:

Código (mysql) [Seleccionar]
mysql> SELECT AES_DECRYPT(UNHEX('6D9E4A37311B9A9FAB28BB183020341FADB51A99E038F22213B44876F88FD15A'), 'password');
+----------------------------------------------------------------------------------------------------+
| AES_DECRYPT(UNHEX('6D9E4A37311B9A9FAB28BB183020341FADB51A99E038F22213B44876F88FD15A'), 'password') |
+----------------------------------------------------------------------------------------------------+
| textoquequierocifrar                                                                               |
+----------------------------------------------------------------------------------------------------+
1 row in set (0,00 sec)



En el caso que quieran descifrar el de 128 bits no van a poder, deberán volver a cambiar la variable global a 128 bits para que puedan realizar el descifrado.

Espero que les sirva, pueden aprovechar esta función al máximo para poder brindarle una mayor seguridad y privacidad a los usuarios de sus sistemas. Pueden usarlo para cifrar información personal del usuario y a menos que el no ponga su password, que también se debe guardar cifrada, no se pueda ver la información personal. De esa manera ni el administrador podrá leer la información personal y se le dará una mayor privacidad al usuario. Sé que se lee redundante pero es complicado de explicar un uso masivo. Ya haré un post sobre como usarlo de manera masivo con varios usuarios y su información.


FUENTE (http://blog.dedalo.in/post/2014/10/17/Uso-seguro-de-AES-ENCRYPT-con-Mysql)

Saludos,
Dedalo.
Título: Re:Uso seguro de AES ENCRYPT con MySQL
Publicado por: ANTRAX en Octubre 19, 2014, 04:05:44 PM
Muy pero muy bueno bro!!
Muchisimas gracias y ahora me pondré a verlo bien en detalle!

Saludos!
ANTRAX
Título: Re:Uso seguro de AES ENCRYPT con MySQL
Publicado por: arthusu en Octubre 19, 2014, 04:57:25 PM
block_encryption_mode solo funciona en versiones  5.6.17 o mayores en MySQL, saludos y buen post Dedalo +1
Título: Re:Uso seguro de AES ENCRYPT con MySQL
Publicado por: Dedalo en Octubre 19, 2014, 05:01:45 PM
Gracias a los 2 :) y si arthusu si das click al link de la web de developers de mysql que puse sale desde que versión funciona así.


Saludos,
Dedalo.