¿Cómo puedo encriptar datos en MySQL?

Cifrado en Bases de Datos MySQL

Valoración: 4 (7969 votos)

En la era digital actual, los datos son un activo de incalculable valor. Proteger esta información es fundamental, y naturalmente, esto incluye asegurar las bases de datos donde reside. No basta con una única capa de defensa; la seguridad de los datos exige un enfoque integral y multifacético. El cifrado, o encriptación, es una de las capas más críticas en esta estrategia.

Cuando hablamos de cifrado en el contexto de MySQL, nos referimos principalmente a dos escenarios distintos pero complementarios: el cifrado de los datos tal como están almacenados en la base de datos (datos en reposo) y el cifrado de las conexiones entre los clientes y el servidor de MySQL (datos en tránsito). Cada uno de estos escenarios utiliza métodos y mecanismos específicos que exploraremos en detalle.

¿Está cifrada la base de datos MySQL?
MySQL utiliza el protocolo de Seguridad de la Capa de Transporte (TLS) con OpenSSL para el cifrado de datos en tránsito . Los programas MySQL establecen conexiones cifradas por defecto si dicho cifrado está habilitado (y es compatible) en el servidor. Las conexiones sin cifrar fallan.
Índice de Contenido

Principios Básicos del Cifrado

El cifrado es el proceso de transformar información legible (texto plano) en un formato ilegible (texto cifrado) para cualquier persona que no posea la clave o mecanismo adecuado. El objetivo es ocultar la información de accesos no autorizados. Este proceso se rige por un algoritmo, conocido como cifrador, que define tanto el proceso de cifrado como el de descifrado.

El elemento central del cifrado es la clave. Es una pieza de información que determina cómo se cifra y descifra un conjunto de datos. Dependiendo del tipo de cifrado, puede ser una única clave o un par de claves. Los dos tipos principales de cifrado son el simétrico y el asimétrico.

Cifrado Simétrico vs. Asimétrico

La diferencia fundamental entre el cifrado simétrico y el asimétrico radica en el número y uso de las claves:

CaracterísticaCifrado SimétricoCifrado Asimétrico
Número de ClavesUna única claveUn par de claves (pública y privada)
Uso de ClavesLa misma clave para cifrar y descifrarClave pública para cifrar, clave privada para descifrar
VelocidadGeneralmente más rápidoGeneralmente más lento
Complejidad de Gestión de ClavesRequiere compartir la clave de forma seguraLa clave pública se puede compartir libremente; la privada debe mantenerse secreta
Aplicaciones TípicasCifrado de archivos, discos, bases de datosFirmas digitales, intercambio seguro de claves, SSL/TLS

El cifrado simétrico es conocido por su velocidad y eficiencia, lo que lo hace ideal para cifrar grandes volúmenes de datos, como bases de datos completas o archivos. Requiere que ambas partes (quien cifra y quien descifra) compartan la misma clave de forma segura.

El cifrado asimétrico, aunque más lento, resuelve el problema del intercambio seguro de claves del cifrado simétrico. Utiliza un par de claves matemáticamente relacionadas: una clave pública que se puede compartir libremente para cifrar mensajes o verificar firmas, y una clave privada que debe mantenerse en secreto para descifrar mensajes o crear firmas digitales. Es fundamental para establecer comunicaciones seguras y verificar identidades.

Cifrado de Datos en Reposo en MySQL

El cifrado de datos en reposo se refiere a la protección de la información almacenada persistentemente en el disco. En el contexto de MySQL, esto se aplica principalmente a los datos dentro de los ficheros de la base de datos. El motor de almacenamiento por defecto y más común en MySQL, InnoDB, soporta nativamente el cifrado de datos en reposo.

Este tipo de cifrado se puede aplicar a varios componentes de InnoDB, incluyendo tablespaces generales, tablespaces por tabla, el tablespace del sistema MySQL, y los ficheros de registro (redo logs y undo logs). Al cifrar estos elementos, te aseguras de que, incluso si los ficheros de datos son accedidos directamente fuera del entorno de MySQL (por ejemplo, si un disco duro es robado), la información dentro de ellos sea ilegible sin las claves adecuadas.

La arquitectura de cifrado de datos en reposo en MySQL, específicamente con InnoDB, utiliza un enfoque de dos niveles de claves:

  1. Clave Maestra de Cifrado (Master Encryption Key): Es la clave de nivel superior. Se almacena externamente a los ficheros de datos de la base de datos, típicamente gestionada por un plugin de keyring.
  2. Claves de Tablespace (Tablespace Keys): Cada tablespace cifrado tiene su propia clave única. Esta clave de tablespace se cifra utilizando la clave maestra de cifrado y se almacena en la cabecera del propio fichero del tablespace.

Cuando un usuario o aplicación autorizada intenta acceder a datos en un tablespace cifrado, MySQL primero utiliza la clave maestra para descifrar la clave de tablespace almacenada en la cabecera. Una vez descifrada la clave de tablespace (que permanece sin cifrar en memoria), se utiliza para descifrar los datos contenidos en ese tablespace específico.

Una característica importante de este sistema es la rotación de clave maestra. Aunque las claves de tablespace descifradas no cambian, la clave maestra sí puede ser cambiada periódicamente. Al rotar la clave maestra, la clave de tablespace cifrada se vuelve a cifrar utilizando la nueva clave maestra. Esto mejora la seguridad al limitar la cantidad de datos cifrados con una única versión de la clave maestra. Para gestionar la clave maestra, MySQL utiliza el plugin keyring, disponible en todas las ediciones de MySQL y que almacena la clave maestra en un fichero local o se integra con sistemas de gestión de claves externos.

Métodos Específicos de Cifrado y Hashing en MySQL

MySQL proporciona funciones y mecanismos para implementar el cifrado y el hashing, ya sea a nivel de almacenamiento (InnoDB) o a nivel de aplicación (utilizando funciones SQL).

AES: El Estándar en MySQL

El estándar de cifrado avanzado (AES, por sus siglas en inglés) es el algoritmo de cifrado por defecto utilizado por InnoDB para el cifrado de datos en reposo. Es un algoritmo de cifrado simétrico, lo que significa que utiliza la misma clave para cifrar y descifrar. AES es ampliamente reconocido por su robustez y eficiencia.

AES opera con claves de longitud variable: 128, 192 o 256 bits. La longitud de la clave determina el número de 'rondas' de transformaciones que el algoritmo aplica a los datos. Por ejemplo, una clave de 128 bits utiliza 10 rondas, 192 bits usa 12 rondas, y 256 bits usa 14 rondas. AES procesa datos en bloques de 128 bits (equivalente a 16 bytes).

Además del cifrado a nivel de tablespace con InnoDB, MySQL también ofrece funciones SQL para cifrar y descifrar datos a nivel de columna o aplicación utilizando AES. Estas son:

AES_ENCRYPT('cadena', 'clave')
AES_DECRYPT('cadena', 'clave')

Donde 'cadena' son los datos a cifrar/descifrar (pueden ser texto, números o datos binarios) y 'clave' es la contraseña o clave secreta utilizada para ambas operaciones. Es crucial que la 'clave' utilizada para descifrar sea exactamente la misma que se usó para cifrar. Si alguno de los parámetros es NULL, la función devuelve NULL.

Veamos un ejemplo práctico utilizando una columna de la base de datos de ejemplo sakila. Supongamos que queremos cifrar los números de teléfono almacenados en la columna phone de la tabla address.

Primero, añadimos una nueva columna para almacenar los datos cifrados:

ALTER TABLE address ADD COLUMN encrypted_phone VARBINARY(128);

Luego, ciframos los datos de la columna phone y los almacenamos en la nueva columna. Usamos una clave de ejemplo '12345678', pero en un entorno de producción, se debe usar una clave robusta y gestionada de forma segura:

UPDATE address SET encrypted_phone = AES_ENCRYPT(phone,'miclavesecreta123');

Para verificar que el cifrado funcionó, podemos consultar los datos cifrados (que aparecerán como datos binarios ilegibles) y los datos originales:

SELECT address, phone, encrypted_phone FROM address LIMIT 5;

Finalmente, para descifrar los datos y confirmar que se recuperan correctamente, usamos la función AES_DECRYPT() con la misma clave:

SELECT address, phone, AES_DECRYPT(encrypted_phone, 'miclavesecreta123') AS decrypted_phone FROM address LIMIT 5;

Si todo es correcto, la columna decrypted_phone mostrará los números de teléfono originales. Este método permite cifrar datos sensibles a nivel de aplicación si el cifrado de tablespace completo no es deseado o posible.

Es importante mencionar que AES reemplazó al antiguo estándar DES (Data Encryption Standard), que utilizaba una clave mucho más corta (56 bits) y se considera inseguro para los estándares actuales. DES fue marcado como obsoleto en MySQL 5.7 y eliminado por completo en MySQL 8.0.

Hashing con SHA2

El hashing es un proceso diferente al cifrado. Mientras que el cifrado es una transformación bidireccional (se puede cifrar y descifrar), el hashing es una transformación unidireccional. Convierte una entrada (un mensaje, una cadena) en una cadena de caracteres de longitud fija, llamada hash o resumen. Es computacionalmente inviable obtener la entrada original a partir del hash.

Los hashes se utilizan comúnmente para verificar la integridad de los datos (cualquier pequeño cambio en la entrada produce un hash completamente diferente) y para almacenar contraseñas de forma segura (se almacena el hash de la contraseña en lugar de la contraseña en texto plano, y para verificar un inicio de sesión, se hashea la contraseña proporcionada y se compara con el hash almacenado). Las firmas digitales y los certificados SSL se basan en técnicas de hashing.

MySQL soporta funciones de hashing, siendo SHA2() la recomendada por ser más segura que algoritmos más antiguos como SHA1. La función SHA2() calcula un hash utilizando la familia de algoritmos SHA-2.

La sintaxis es:

SHA2(cadena_a_hashear, longitud_bits)

'cadena_a_hashear' es la cadena de texto plano que quieres hashear. 'longitud_bits' es la longitud deseada del hash resultante, permitiéndose valores como 224, 256, 384 o 512. Si se proporciona NULL o una longitud no permitida, la función devuelve NULL.

Ejemplos:

SELECT SHA2('mi_contrasena_segura', 256);
SELECT SHA2('otro_texto', 512);

Es importante notar que la función SHA2() (y otras funciones criptográficas) solo está disponible si MySQL se compiló con soporte para SSL.

¿Cuáles son los tipos de cifrado de datos?
Los dos tipos principales de cifrado son el cifrado simétrico y el cifrado asimétrico. - Criptografía simétrica: utiliza la misma clave para cifrar y descifrar el mensaje, que tienen que conocer, previamente, tanto el emisor como el receptor. - Criptografía asimétrica: se basa en el uso de dos claves.

Generación de Bytes Aleatorios con RANDOM_BYTES

La función RANDOM_BYTES() genera una cadena binaria de bytes aleatorios utilizando la librería SSL subyacente. Es útil para generar datos aleatorios que pueden servir como claves de cifrado, sales (salts) para hashing de contraseñas, o simplemente datos aleatorios seguros. La longitud de la cadena binaria resultante puede especificarse, desde 1 hasta 1024 bytes.

La sintaxis es:

RANDOM_BYTES(longitud)

Si 'longitud' es NULL, la función devuelve NULL.

Un caso de uso común es generar contraseñas aleatorias o claves de cifrado únicas para usuarios o registros. El siguiente ejemplo genera una clave de cifrado aleatoria de 32 bytes (256 bits) para los primeros 5 clientes de la tabla customer, codificada en Base64 para hacerla más legible:

SELECT customer_id, first_name, last_name, TO_BASE64(RANDOM_BYTES(32)) AS clave_cifrado FROM customer LIMIT 5;

Estas funciones (AES_ENCRYPT, AES_DECRYPT, SHA2, RANDOM_BYTES) son herramientas poderosas para implementar seguridad a nivel de aplicación o para complementar el cifrado de datos en reposo gestionado por InnoDB y el plugin keyring.

Cifrado de Datos en Tránsito en MySQL

El cifrado de datos en tránsito se enfoca en proteger la información mientras se mueve a través de una red, por ejemplo, entre un cliente de base de datos (como una aplicación o una herramienta de administración) y el servidor de MySQL. Su propósito es evitar que terceros intercepten y lean los datos que se transmiten. MySQL utiliza el protocolo TLS (Transport Layer Security), sucesor de SSL, junto con OpenSSL para habilitar conexiones cifradas.

Cuando el cifrado TLS está habilitado y configurado correctamente en el servidor MySQL, los programas cliente de MySQL pueden establecer conexiones cifradas. Es posible configurar el servidor para requerir que todas las conexiones sean cifradas, rechazando cualquier intento de conexión no cifrada. Esto garantiza que la comunicación entre el cliente y el servidor siempre esté protegida contra espionaje.

El proceso implica que los datos se cifran en el origen (el cliente o el servidor) antes de ser enviados por la red y se descifran en el destino. Esto protege los datos mientras viajan por la red, que a menudo puede ser una ruta insegura.

En MariaDB, un fork de MySQL, el cifrado en tránsito no siempre está activado por defecto, pero si el servidor está compilado con soporte TLS, se puede configurar para usar conexiones cifradas.

Comprobando el Cifrado y los Protocolos TLS

Es crucial poder verificar si el servidor MySQL soporta cifrado TLS y si las conexiones actuales o requeridas están cifradas. MySQL proporciona variables de sistema y tablas de rendimiento que permiten hacer estas comprobaciones.

Para verificar si el servidor soporta cifrado SSL/TLS, puedes usar la siguiente consulta:

SHOW VARIABLES LIKE 'have_ssl';

Si el valor de have_ssl es YES, el servidor tiene soporte para SSL/TLS.

Para ver qué versiones del protocolo TLS soporta el servidor, utiliza:

SHOW VARIABLES LIKE 'tls_version';

La salida mostrará una lista de las versiones de TLS soportadas (por ejemplo, 'TLSv1.2, TLSv1.3').

Para saber si el servidor está configurado para requerir que todas las conexiones entrantes sean cifradas, consulta:

SHOW VARIABLES LIKE 'require_secure_transport';

Si el valor es ON, solo se permitirán conexiones cifradas.

Finalmente, para determinar si una conexión específica (o las conexiones principales) está activa y cifrada, puedes consultar la tabla performance_schema.tls_channel_status (disponible en MySQL 8.0 y posteriores):

SELECT * FROM performance_schema.tls_channel_status WHERE CHANNEL='mysql_main' AND PROPERTY='Enabled';

Si la columna VALUE muestra YES para el canal principal, significa que las conexiones a través de ese canal están cifradas.

Preguntas Frecuentes sobre Cifrado en MySQL

¿MySQL cifra los datos por defecto?

No, MySQL no cifra los datos ni las conexiones por defecto. El cifrado de datos en reposo (con InnoDB) y el cifrado de datos en tránsito (con TLS) deben ser configurados y habilitados explícitamente.

¿Cuál es la diferencia entre cifrado y hashing?

El cifrado es un proceso bidireccional que permite transformar datos legibles en ilegibles (cifrar) y viceversa (descifrar) utilizando una clave. El hashing es un proceso unidireccional que transforma datos en una cadena de longitud fija (hash) de la cual es computacionalmente imposible recuperar los datos originales. El cifrado se usa para proteger la confidencialidad de los datos, mientras que el hashing se usa típicamente para verificar la integridad de los datos o almacenar contraseñas de forma segura.

¿AES cifra toda la base de datos automáticamente?

El cifrado de datos en reposo con InnoDB (que usa AES) se configura a nivel de tablespace. Puedes cifrar tablespaces individuales, tablespaces generales, o el tablespace del sistema, pero requiere configuración específica. Las funciones AES_ENCRYPT()/AES_DECRYPT() permiten cifrar datos a nivel de columna o aplicación, no automáticamente toda la base de datos.

¿Es SHA1 seguro para contraseñas?

SHA1 es un algoritmo de hashing más antiguo (genera un hash de 160 bits) y se considera criptográficamente débil frente a ataques de colisión. No es recomendable para nuevas aplicaciones, especialmente para el almacenamiento seguro de contraseñas. Se prefiere el uso de algoritmos de la familia SHA-2, como SHA256 o SHA512, o algoritmos de hashing de contraseñas diseñados específicamente como bcrypt o scrypt.

¿Cómo habilito el cifrado de conexiones (TLS)?

Habilitar el cifrado TLS requiere configurar certificados SSL/TLS en el servidor MySQL y, opcionalmente, en el cliente. Una vez configurado, puedes instruir a los clientes para que intenten o requieran conexiones seguras. Las opciones de configuración varían ligeramente entre versiones de MySQL y configuraciones específicas.

Conclusión

El cifrado es una parte esencial de cualquier estrategia de seguridad de bases de datos robusta. En MySQL, tienes la capacidad de proteger tus datos tanto cuando están almacenados en el disco (datos en reposo) utilizando el cifrado de tablespace de InnoDB con el plugin keyring y el algoritmo AES, como cuando se transmiten a través de la red (datos en tránsito) mediante el protocolo TLS.

Además, MySQL ofrece funciones SQL como AES_ENCRYPT(), AES_DECRYPT(), SHA2() y RANDOM_BYTES() que permiten añadir capas de seguridad a nivel de aplicación o de columna específica. Implementar una combinación adecuada de estas técnicas, junto con otras prácticas de seguridad como la gestión de usuarios y permisos, auditoría y backups seguros, es fundamental para garantizar la confidencialidad e integridad de tu información en MySQL.

Comprender y configurar correctamente estas opciones de cifrado es vital para proteger la información sensible de accesos no autorizados, cumpliendo así con normativas de privacidad y seguridad de datos cada vez más estrictas.

Si quieres conocer otros artículos parecidos a Cifrado en Bases de Datos MySQL puedes visitar la categoría Seguridad.

Ivan

Soy un entusiasta de la tecnología con especialización en bases de datos, particularmente en MySQL. A través de mis tutoriales detallados, busco desmitificar los conceptos complejos y proporcionar soluciones prácticas a los desafíos cotidianos relacionados con la gestión de datos

Aprende mas sobre MySQL

Subir