SHA1 y SHA2 en MySQL
Las funciones SHA1() y SHA2() en MySQL pertenecen a la familia Secure Hash Algorithm y permiten generar resúmenes criptográficos de mayor fortaleza que MD5. SHA1 produce un hash de 160 bits representado como una cadena hexadecimal de 40 caracteres, mientras que SHA2 ofrece variantes de 224, 256, 384 y 512 bits según el nivel de seguridad requerido. Estas funciones son esenciales cuando necesitas verificar integridad de datos con garantías más sólidas, generar tokens únicos, crear fingerprints de registros o cualquier tarea donde la resistencia a colisiones sea un factor relevante. En esta guía exploraremos ambas funciones en profundidad, con ejemplos progresivos y recomendaciones prácticas para elegir la variante adecuada en cada situación.
Sintaxis de SHA1
La función SHA1, también disponible como su alias SHA(), recibe una cadena de texto y devuelve su hash de 160 bits en formato hexadecimal. El resultado es siempre una cadena en minúsculas de exactamente 40 caracteres, independientemente de la longitud de la entrada.
SHA1(cadena)
-- o su alias equivalente:
SHA(cadena)Al igual que otras funciones de hash en MySQL, SHA1 es determinista: la misma entrada siempre produce la misma salida. Si el argumento es NULL, el resultado también será NULL. La función procesa la cadena byte a byte, por lo que la codificación de caracteres de la conexión influye en el resultado final.
SELECT SHA1('Tutorial MySQL');
-- Resultado: cadena hexadecimal de 40 caracteres
SELECT SHA1('tutorial mysql');
-- Resultado diferente, SHA1 distingue mayúsculas
SELECT SHA1(NULL);
-- Resultado: NULLSHA1 fue diseñada por la NSA en 1995 como sucesora de SHA-0. Aunque en 2017 Google demostró la primera colisión práctica en SHA1, el algoritmo sigue siendo útil para tareas de integridad no críticas y es considerablemente más robusto que MD5.
Sintaxis de SHA2
La función SHA2 es la evolución moderna de SHA1 y acepta dos parámetros: la cadena a procesar y la longitud del hash deseado en bits. Este segundo parámetro determina qué variante del algoritmo SHA-2 se utiliza, y puede tomar los valores 224, 256, 384 o 512.
SHA2(cadena, longitud_hash)Cada variante produce un resultado de longitud fija en caracteres hexadecimales. SHA2 con 224 bits genera 56 caracteres, con 256 bits genera 64 caracteres, con 384 bits genera 96 caracteres y con 512 bits genera 128 caracteres. Si se proporciona una longitud no válida, la función devuelve NULL.
SELECT SHA2('Tutorial MySQL', 224);
-- Resultado: 56 caracteres hexadecimales
SELECT SHA2('Tutorial MySQL', 256);
-- Resultado: 64 caracteres hexadecimales
SELECT SHA2('Tutorial MySQL', 384);
-- Resultado: 96 caracteres hexadecimales
SELECT SHA2('Tutorial MySQL', 512);
-- Resultado: 128 caracteres hexadecimales
SELECT SHA2('Tutorial MySQL', 128);
-- Resultado: NULL (longitud no válida)La variante SHA2(valor, 256) es la más utilizada y recomendada como estándar general. Ofrece un equilibrio óptimo entre seguridad y rendimiento, y es el algoritmo que subyace a tecnologías tan exigentes como Bitcoin y muchos protocolos de autenticación modernos.
Diferencias entre SHA1 y SHA2
Entender las diferencias entre ambas funciones te ayudará a elegir la correcta para cada caso de uso. La diferencia fundamental radica en la fortaleza criptográfica y la resistencia a colisiones.
SHA1 genera un hash de 160 bits, lo que ofrece un espacio de 2^160 valores posibles. Aunque este número es astronómico, la colisión demostrada en 2017 reveló debilidades estructurales en el algoritmo. SHA2-256, en cambio, ofrece un espacio de 2^256 valores, y hasta la fecha no se han encontrado colisiones ni debilidades prácticas en ninguna de sus variantes.
-- Comparación directa de las tres funciones
SELECT
MD5('datos sensibles') AS hash_md5,
SHA1('datos sensibles') AS hash_sha1,
SHA2('datos sensibles', 256) AS hash_sha256;En términos de rendimiento, SHA1 es ligeramente más rápido que SHA2-256 porque produce un hash más corto y realiza menos rondas de computación. Sin embargo, la diferencia es marginal en la mayoría de aplicaciones y no justifica comprometer la seguridad. Cuando procesas millones de registros y la seguridad criptográfica no es un requisito, MD5 sigue siendo la opción más rápida.
-- SHA1: 40 caracteres, más rápido, seguridad moderada
SELECT LENGTH(SHA1('ejemplo')); -- 40
-- SHA2-256: 64 caracteres, algo más lento, seguridad alta
SELECT LENGTH(SHA2('ejemplo', 256)); -- 64
-- SHA2-512: 128 caracteres, el más lento, seguridad máxima
SELECT LENGTH(SHA2('ejemplo', 512)); -- 128Para conocer más sobre cómo MySQL mide la longitud de estas cadenas de resultado, puedes consultar la referencia de LENGTH.
Generar tokens seguros
Una de las aplicaciones más frecuentes de SHA2 es la generación de tokens para autenticación, restablecimiento de contraseñas o acceso a APIs. Combinando SHA2 con datos únicos como marcas de tiempo y valores aleatorios, puedes crear tokens difíciles de predecir.
CREATE TABLE tokens_acceso (
id INT AUTO_INCREMENT PRIMARY KEY,
usuario_id INT NOT NULL,
token CHAR(64) NOT NULL UNIQUE,
tipo ENUM('sesion', 'api', 'recuperacion') NOT NULL,
creado_en DATETIME DEFAULT CURRENT_TIMESTAMP,
expira_en DATETIME NOT NULL,
INDEX idx_token (token)
);
-- Generar un token combinando datos únicos
INSERT INTO tokens_acceso (usuario_id, token, tipo, expira_en)
VALUES (
42,
SHA2(CONCAT(42, NOW(6), RAND(), 'sal_secreta_aplicacion'), 256),
'recuperacion',
DATE_ADD(NOW(), INTERVAL 24 HOUR)
);Para tokens que requieren la máxima seguridad, es preferible combinar SHA2 con RANDOM_BYTES, que genera bytes criptográficamente seguros. La función RAND() de MySQL es un generador pseudoaleatorio que no ofrece garantías criptográficas, por lo que no debería ser la única fuente de entropía.
-- Token más seguro usando RANDOM_BYTES como fuente de entropía
INSERT INTO tokens_acceso (usuario_id, token, tipo, expira_en)
VALUES (
42,
SHA2(CONCAT(42, HEX(RANDOM_BYTES(32)), NOW(6)), 256),
'api',
DATE_ADD(NOW(), INTERVAL 90 DAY)
);Verificar integridad de datos
SHA2 es la opción preferida cuando la verificación de integridad requiere alta confianza. En auditorías, migraciones de datos y sistemas financieros, necesitas garantizar que los datos no han sido alterados ni accidental ni intencionadamente.
CREATE TABLE transacciones_financieras (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
cuenta_origen VARCHAR(24) NOT NULL,
cuenta_destino VARCHAR(24) NOT NULL,
importe DECIMAL(15,2) NOT NULL,
divisa CHAR(3) NOT NULL,
fecha_operacion DATETIME NOT NULL,
hash_verificacion CHAR(64) NOT NULL,
verificado BOOLEAN DEFAULT FALSE
);
-- Insertar transacción con hash de integridad
INSERT INTO transacciones_financieras
(cuenta_origen, cuenta_destino, importe, divisa, fecha_operacion, hash_verificacion)
VALUES (
'ES76 2100 0813 6101 2345 6789',
'ES91 2100 0418 4502 0005 1332',
15750.00,
'EUR',
'2026-03-24 10:30:00',
SHA2(CONCAT_WS('|',
'ES76 2100 0813 6101 2345 6789',
'ES91 2100 0418 4502 0005 1332',
'15750.00',
'EUR',
'2026-03-24 10:30:00'
), 256)
);La verificación posterior recalcula el hash con los datos actuales y lo compara con el almacenado. Cualquier modificación, por mínima que sea, producirá un hash completamente diferente.
-- Auditoría de integridad: detectar transacciones alteradas
SELECT
id,
cuenta_origen,
importe,
CASE
WHEN hash_verificacion = SHA2(CONCAT_WS('|',
cuenta_origen, cuenta_destino, importe, divisa, fecha_operacion
), 256)
THEN 'Válida'
ELSE 'ALTERADA - Requiere revisión'
END AS estado_integridad
FROM transacciones_financieras
WHERE fecha_operacion >= '2026-03-01';Crear fingerprints de registros
Los fingerprints (huellas digitales) de registros permiten detectar cambios en filas completas sin necesidad de comparar cada columna individualmente. Esta técnica es invaluable durante sincronizaciones entre bases de datos, replicación selectiva o detección de cambios en sistemas de caché.
-- Tabla de clientes con fingerprint SHA2
CREATE TABLE clientes (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(100) NOT NULL,
email VARCHAR(150) NOT NULL,
telefono VARCHAR(20),
direccion TEXT,
ciudad VARCHAR(80),
fingerprint CHAR(64) NOT NULL,
ultima_modificacion DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Calcular fingerprint al insertar
INSERT INTO clientes (nombre, email, telefono, direccion, ciudad, fingerprint)
VALUES (
'María López Fernández',
'maria.lopez@ejemplo.com',
'+34 612 345 678',
'Calle Mayor 15, 3ºB',
'Madrid',
SHA2(CONCAT_WS('|',
'María López Fernández',
'maria.lopez@ejemplo.com',
'+34 612 345 678',
'Calle Mayor 15, 3ºB',
'Madrid'
), 256)
);Para sincronizar datos entre dos sistemas, basta con comparar los fingerprints. La función CONCAT es fundamental aquí para unir todos los campos en una sola cadena antes de calcular el hash.
-- Detectar registros que difieren entre producción y réplica
SELECT p.id, p.nombre, p.email
FROM produccion.clientes p
JOIN replica.clientes r ON p.id = r.id
WHERE p.fingerprint != r.fingerprint;
-- Actualizar fingerprint tras modificación
UPDATE clientes
SET
email = 'maria.nueva@ejemplo.com',
fingerprint = SHA2(CONCAT_WS('|',
nombre, 'maria.nueva@ejemplo.com', telefono, direccion, ciudad
), 256)
WHERE id = 1;Nota sobre contraseñas y SHA2
Aunque SHA2 es un algoritmo criptográficamente robusto, no fue diseñado específicamente para el almacenamiento de contraseñas. La mejor práctica actual es usar funciones de hashing adaptativo como bcrypt, scrypt o Argon2 desde la capa de aplicación. Estas funciones incorporan un factor de coste configurable que las hace deliberadamente lentas, dificultando los ataques de fuerza bruta.
Dicho esto, SHA2 combinado con una sal única por usuario es una solución aceptable para generar tokens, claves de API y otros valores que no son contraseñas propiamente dichas.
-- Ejemplo de hash con sal para un token (NO para contraseñas de login)
SET @sal = HEX(RANDOM_BYTES(16));
SET @valor = 'token_base_usuario_42';
SELECT SHA2(CONCAT(@sal, ':', @valor), 256) AS token_con_sal;La sal garantiza que incluso si dos usuarios generan tokens a partir del mismo valor base, los resultados serán completamente distintos. Para generar sales criptográficamente seguras dentro de MySQL, RANDOM_BYTES es la función indicada.
Errores comunes al usar SHA1 y SHA2
El error más frecuente con SHA2 es proporcionar un valor de longitud no soportado como segundo parámetro. MySQL solo acepta 224, 256, 384 y 512. Cualquier otro valor, incluyendo 0 o 128, devuelve NULL silenciosamente sin generar un error.
SELECT SHA2('datos', 256); -- Funciona: 64 caracteres
SELECT SHA2('datos', 512); -- Funciona: 128 caracteres
SELECT SHA2('datos', 128); -- Devuelve NULL (no soportado)
SELECT SHA2('datos', 0); -- Devuelve NULLOtro error habitual es dimensionar incorrectamente la columna que almacena el hash. Si usas CHAR(40) pensando en SHA1 pero después cambias a SHA2-256, los hashes de 64 caracteres se truncarán silenciosamente, corrompiendo todos tus datos de verificación.
-- Dimensionar correctamente según la variante
-- SHA1: CHAR(40)
-- SHA2-224: CHAR(56)
-- SHA2-256: CHAR(64)
-- SHA2-384: CHAR(96)
-- SHA2-512: CHAR(128)También es común olvidar que el alias SHA() es equivalente a SHA1(), no a SHA2(). Algunos desarrolladores asumen que SHA() utiliza el algoritmo más reciente, pero en realidad devuelve un hash SHA1 de 40 caracteres.
Cuándo usar SHA1 y cuándo SHA2
SHA1 es apropiado para tareas internas donde la velocidad es prioritaria y la resistencia a ataques deliberados no es un requisito. Por ejemplo, generar identificadores para sistemas de caché internos o crear checksums rápidos durante ETL.
SHA2-256 debería ser tu elección por defecto cuando la integridad de los datos tiene implicaciones de seguridad. Tokens de autenticación, verificación de transacciones financieras, fingerprints de registros en sistemas de auditoría y cualquier escenario donde necesites confiar en que el hash no puede ser manipulado. Si el volumen de datos es extremo y cada microsegundo cuenta en operaciones masivas, MD5 puede ser una alternativa razonable siempre que la seguridad no sea un factor.
SHA2-512 es la opción más conservadora, ideal cuando necesitas la máxima seguridad posible dentro de MySQL, por ejemplo para firmar datos que serán verificados por sistemas externos. El coste adicional de rendimiento respecto a SHA2-256 es moderado y generalmente aceptable.
Escrito por Eduardo Lázaro
