Publicado el Jueves 12 de junio de 2008 a las 09:46:59 por abenavidescr
Lecturas
Introducción
Almacenar contraseñas en MySQL como texto plano (sin encriptar) nunca será una buena idea. Como buenos administradores de bases de datos debemos tener cuidado de proteger la información de nuestros usuarios. Afortunadamente MySQL provee diversas opciones para proteger contraseñas.
Después de darle una rápida revisada al manual de MySQL, podemos estar tentados a guardar las contraseñas utilizando la función PASSWORD(), sin embargo esta no es una muy buena recomendación. La misma gente de MySQL advierte sobre el uso de esta función para almacenar contraseñas.
En vez de la función PASSWORD(), podemos usar SHA1 y MD5. Y aunque se han encontrado formas de romper contraseñas que utilizan estos métodos de encriptación, simpre será mejor tener esta opción a la de contraseñas en texto plano.
En efecto, podemos aplicar el algoritmo SHA1 a una cadena que represente una contraseña:
mysql> select SHA1('unapalabrasecreta');
+------------------------------------------+
| SHA1('unapalabrasecreta') |
+------------------------------------------+
| 49866def688c2c33cce5f449019f3f0d3da804c7 |
+------------------------------------------+
1 row in set (0.07 sec)
Puesto que SHA es un alias para SHA1, se produce el mismo resultado.
mysql> select SHA('unapalabrasecreta');
+------------------------------------------+
| SHA('unapalabrasecreta') |
+------------------------------------------+
| 49866def688c2c33cce5f449019f3f0d3da804c7 |
+------------------------------------------+
1 row in set (0.00 sec)
Para almacenar contraseñas que estén encriptadas con SHA1, necesitamos una cadena de 40 caracteres.
mysql> SELECT CHARACTER_LENGTH(SHA1('unapalabrasupersecreta'));
+--------------------------------------------------+
| CHARACTER_LENGTH(SHA1('unapalabrasupersecreta')) |
+--------------------------------------------------+
| 40 |
+--------------------------------------------------+
1 row in set (0.06 sec)
Por el otro lado, para almacenar contraseñas encriptadas con MD5, necesitamos una cadena de 32 caracteres.
mysql> SELECT MD5('unapalabrasecreta');
+----------------------------------+
| MD5('unapalabrasecreta') |
+----------------------------------+
| adf5f3246000cfba3bcba28917fc6a89 |
+----------------------------------+
1 row in set (0.00 sec)
mysql> SELECT CHARACTER_LENGTH(MD5('unapalabrasecreta'));
+--------------------------------------------+
| CHARACTER_LENGTH(MD5('unapalabrasecreta')) |
+--------------------------------------------+
| 32 |
+--------------------------------------------+
1 row in set (0.00 sec)
MD5
La función MD5() calcula el checksum de 128 bits de una cadena. El valor que devuelve esta función es una cadena binaria de 32 dggitos hexadecimales o NULL si la cadena original es NULL.
Usar MD5 en nuestras aplicaciones es realmente fácil. A continuación se muestra como escribir las consultas para que hagan uso de MD5, y tomen ventaja de este algoritmo de encriptación.
Finalmente, vamos a ver como quedaría la consulta que lleva a cabo la autenticación de los usuarios.
mysql> SELECT * FROM usuarios_md5 WHERE usr='fulanito' AND passwd=MD5('fulanito123');
+----------+----------------------------------+
| usr | passwd |
+----------+----------------------------------+
| fulanito | f331d3f903782b929b9887c60eb8d4e6 |
+----------+----------------------------------+
1 row in set (0.00 sec)
SHA1
La función SHA1() calcula el checksum SHA de 160 bits de una cadena. El valor que devuelve esta función es una cadena de 40 dígitos hexadecimales o NULL si la cadena original es NULL.
Ahora veamos el caso de las contraseñas encriptadas con el algoritmo SHA1, el cual es "criptográficamente más seguro" que MD5. Debemos notar que se redefine el campo de la contraseña para que tenga una longitud de 40 caracteres.
mysql> SELECT * FROM usuarios_sha1 WHERE usr='fulanito' AND passwd=SHA1('fulanito123');
+----------+------------------------------------------+
| usr | passwd |
+----------+------------------------------------------+
| fulanito | 23e0199ee9495df1542a431259141bd5a8d0ec50 |
+----------+------------------------------------------+
1 row in set (0.00 sec)
AES
Como se mencionó anteriormente, se han encontrado formas de romper contraseñas que estén encriptadas con MD5 o SHA1, por lo que es probable que estas funciones no nos proporcionen el nivel de protección y seguridad que necesitamos o que deseamos. Afortunadamente, MySQL proporciona una alternativa más llamada AES (Advanced Encryption Standard).
Para implementar encriptación con AES, necesitamos especificar que el campo de la contraseña sea del tipo BLOB. Las funciones AES codifican con una llave de 128-bits de longitud, sin embargo este valor puede ser ajustado modificando el código fuente y re-compilando MySQL.
Ahora vamos a insertar un registro. A diferencia de MD5 y SHA1, al almacenar contraseñas con AES se tiene que proporcionar una cadena adicional que será la llave para encriptar y desencriptar.
Entonces, para autenticar un usuario, encriptamos la contraseña que el usuario está usuando para validarse y la llave previamente usada. De esta forma se puede hacer el match con el registro en la tabla.
mysql> SELECT * FROM usuarios_aes WHERE usr='fulanito' AND passwd=AES_ENCRYPT('fulanito123','lallavesecreta');
+----------+------------------+
| usr | passwd |
+----------+------------------+
| fulanito | º►J-=9¨gÿ'à 9ıNâW |
+----------+------------------+
1 row in set (0.00 sec)
Puesto que AES provee encriptación reversible (siempre y cuando tengamos la llave apropiada), podemos obtener las contraseñas en texto plano.
mysql> SELECT usr, AES_DECRYPT(passwd, 'lallavesecreta') AS passwd FROM usuarios_aes;
+----------+-------------+
| usr | passwd |
+----------+-------------+
| fulanito | fulanito123 |
+----------+-------------+
1 row in set (0.00 sec)
De acuerdo a MySQL, las funciones AES (AES_ENCRYPT() y AES_DECRYPT()) fueron agregadas a partir de la versión 4.0.2 y actualmente son las funciones criptográficas más seguras en MySQL.
Si MySQL ha sido configurado con soporte SSL, podemos usar funciones DES, las cuales usan el algoritmo Triple-DES para encriptar una cadena con una cierta llave.
Hey, buen articulo. Yo siempre he sido de los que buscan hacer las cosas por si mismo, pero estas funciones de MySQL que desconocia son bastante seguras, ademas de la función AES que da aun mas seguridad. Bien por el articulo y estare esperando a que subas la siguiente parte!.