Cifrado de datos en MySQL con AES

Publicado por parzibyte en

AES (Advanced encryption standard) es un algoritmo bastante fuerte y seguro, utilizado ampliamente en el mundo de la seguridad informática.

MySQL permite cifrar y descifrar datos utilizando el algoritmo AES a través de las funciones aes_encrypt y aes_decrypt.

Cifrar y descifrar con AES en MySQL

De esta manera podemos proteger y asegurar datos utilizando AES.

En este post vamos a ver cómo cifrar y descifrar datos con AES en MySQL.

Sintaxis de aes_encrypt y aes_decrypt

Ambas funciones trabajan de una manera similar. Reciben como primer argumento el texto a cifrar o descifrar, y como segundo argumento la clave.

Es decir:

aes_encrypt("texto_plano", "clave")

Y:

aes_decrypt("texto_cifrado", "clave")

Es importante mencionar que al encriptar se devuelven datos binarios, así que hay que definir (dentro de la tabla) el tipo de dato como BLOB, o utilizar una alternativa que veremos más abajo.

Ejemplo de cifrado y descifrado AES con MySQL

Primero, una consideración sobre la contraseña: nunca guardes la contraseña o clave de cifrado en la base de datos, guárdala en un lugar separado o ni siquiera la guardes.

Es decir, si la encriptación de datos es distinta por usuario haz que la clave sea algo como un hash con su contraseña, o cosas de esas. Si la encriptación es general, usa la misma clave para todos, pero mantenla en un lugar seguro.

Voy a crear esta tabla sin fijarme en relaciones, buenas prácticas ni normalización (si no sabes cómo trabajar con MySQL mira este tutorial):

Estamos definiendo una tabla que guardará tarjetas de crédito.

En este caso el número estará en texto plano pero el CCV estará en BLOB, es decir, en modo binario para que soporte los valores encriptados. Si quieres cifrar más datos, agrégalos y define el tipo como BLOB.

Al insertar un registro vamos a llamar a aes_encrypt:

En texto plano, el CCV es 123. Lo ciframos con la clave hunter2.

Si listamos el contenido de la tabla (o si un atacante la roba) veremos lo siguiente:

1 – Seleccionar y mostrar datos encriptados con AES en MySQL

Son datos raros, incluso la salida podría mostrarse extraña y con espacios extraños; esto es porque el texto ya está cifrado.

Para descifrar se invoca a aes_decrypt pasándole la misma clave con la que hicimos el cifrado, como primer argumento se indica el valor cifrado.

Si indicamos una contraseña errónea, la función devuelve null la mayoría de veces, aunque podría devolver “basura” en algunas ocasiones, es decir, nunca confíes en que siempre devolverá null para claves erróneas:

2 – aes_decrypt devuelve null con contraseña incorrecta

En caso de indicar la clave correcta el dato se muestra en texto plano, es decir, descifrado:

3 – Descifrar con AES en MySQL

Así es como podemos cifrar y descifrar con AES en MySQL. Como lo dije, hay que mantener la clave en otro lugar.

No te confundas, para probar insertamos el dato 123 como CCV y lo ciframos con la clave hunter2.

Fue un ejemplo básico pero podemos adaptarlo a nuestras necesidades o agregarle más características (podríamos definir un alias a la columna) interactuando con la base de datos desde un lenguaje de programación.

Sobra mencionar que podemos hacer un update y todo tipo de consultas o modificaciones que hacemos normalmente.

aes_encrypt y aes_decrypt sin BLOB

Como lo dije, hay una alternativa a utilizar BLOB y es convertir los datos binarios a su representación hexadecimal al guardarlos; y hacer el proceso inverso al seleccionarlos.

La función que convierte un dato a hexadecimal es HEX, y la función que hace lo inverso es UNHEX.

Ahora se puede definir la tabla para que guarde un valor de tipo TEXT y no BLOB:

Al hacer la inserción ciframos con aes_encrypt pero el resultado lo pasamos a través de HEX y el resultado de ésta última invocación es el que se guarda:

Si recuperamos los datos ahora ya estarán como texto, pues tendrán su forma hexadecimal.

4 – Datos cifrados y representados de manera hexadecimal

Para descifrar los datos invocamos a aes_decrypt pero los datos cifrados serán el resultado de invocar a UNHEX:

5 – Descifrar datos usando aes_decrypt y unhex

Eso sí, los datos hexadecimales ocupan más espacio, pero son legibles y portables. Además, no necesitamos declarar el tipo de dato BLOB.

Para terminar, dejo un enlace al manual de MySQL.


parzibyte

He trabajado por más de 4 años en el desarrollo de software con experiencia en Java, PHP, JavaScript, HTML, Node.JS, Python, Android y Go. También he trabajado con bases de datos SQL como MySQL y SQLite, así como con bases de datos NoSQL usando MongoDB.Soy bueno utilizando algunos frameworks y herramientas como Firebase, jQuery, AngularJS, VueJS, CodeIgniter, Laravel, BulmaCSS, Bootstrap y Electron.Otros términos que conozco son: Arduino, GraphQL, API's, REST, AJAX, PouchDB, CouchDB, Experiencia de usuario, buenas prácticas de programación, Webpack, NPM, Administración de servidores y programación de scriptsLa plataforma en la que tengo más experiencia es la web, pero en mis ratos libres realizo unos pequeños ejercicios en C# y C.Estoy aquí para ayudarte a resolver tus problemas de programación y depuración :-)

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

A %d blogueros les gusta esto: