El hashing es el proceso de convertir datos de tamaño arbitrario en una cadena de longitud fija, utilizado para verificar la integridad y almacenar contraseñas de forma segura. Según el Open Web Application Security Project (OWASP, 2025), el uso correcto de las funciones hash previene hasta el 70% de las vulnerabilidades relacionadas con la filtración de credenciales. Los hash criptográficos son la base de las firmas digitales, las tecnologías blockchain y el control de versiones.
Puntos clave
El hashing es el proceso de calcular una función hash que convierte un conjunto arbitrario de datos de entrada en una cadena de bits de longitud fija llamada resumen o valor hash. A diferencia del cifrado, el hashing es un proceso unidireccional: es imposible recuperar los datos originales a partir del hash.
Las funciones hash criptográficas tienen cuatro propiedades obligatorias: determinismo (la misma entrada siempre produce el mismo hash), irreversibilidad (es computacionalmente inviable recuperar la entrada a partir del hash), efecto avalancha (cambiar un bit de la entrada cambia en promedio la mitad de los bits del hash) y resistencia a colisiones (es computacionalmente inviable encontrar dos entradas diferentes con el mismo hash).
Es importante entender la diferencia entre el hashing y el cifrado. El cifrado es un proceso bidireccional: los datos cifrados se pueden descifrar con una clave. El hashing es un proceso unidireccional: después de la transformación, los datos no se pueden recuperar. Esta propiedad hace que el hashing sea ideal para el almacenamiento de contraseñas: el sistema almacena solo el hash, e incluso si la base de datos se filtra, las contraseñas permanecen protegidas.
No todas las funciones hash son igualmente adecuadas para tareas de seguridad. La división en categorías criptográficas y no criptográficas es de vital importancia al elegir un algoritmo para una tarea específica en el desarrollo móvil.
Estas funciones son deliberadamente lentas y complejas para dificultar los ataques de fuerza bruta. Deben ser resistentes a colisiones y ataques de preimagen. La familia SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512) está certificada por NIST y se recomienda para su uso en sistemas gubernamentales. Para el hashing de contraseñas, se utilizan adicionalmente los algoritmos bcrypt, scrypt y Argon2 con complejidad ajustable.
Estas funciones están optimizadas para la velocidad, no para la seguridad. Ejemplos: CityHash, MurmurHash, xxHash. Se utilizan en tablas hash, deduplicación de datos y sumas de verificación para la verificación rápida de integridad de datos no críticos. Es importante no usarlas nunca para almacenar contraseñas o verificar firmas digitales — su alta velocidad las hace vulnerables a ataques de fuerza bruta.
| Tipo | Ejemplos | Ámbito de aplicación |
|---|---|---|
| Criptográficas | SHA-256, SHA-3, bcrypt | Contraseñas, firmas, TLS |
| No criptográficas | MurmurHash, xxHash | Tablas hash, cachés |
| KDF de contraseñas | bcrypt, scrypt, Argon2 | Almacenamiento de contraseñas |
Revisemos los algoritmos de hashing más comunes utilizados en el desarrollo móvil moderno. Cada uno tiene sus fortalezas y debilidades.
SHA-256 es un símbolo de la criptografía moderna, recomendado por NIST como parte del estándar FIPS 180-4. El algoritmo produce un resumen de 256 bits y es un componente central de los protocolos TLS, las redes blockchain y los sistemas de control de versiones. Según un informe de NCC Group (2025), SHA-256 se utiliza en el 96% de los certificados TLS para firmar la transparencia de certificados.
SHA-3 es la familia más nueva de funciones hash, estandarizada por NIST en 2015 como FIPS 202. A diferencia de SHA-2, que se basa en la estructura Merkle–Damgård, SHA-3 se basa en una construcción Keccak diferente con una función esponja. Esto hace que SHA-3 sea resistente a ataques que puedan surgir contra SHA-2 en el futuro. Para los desarrolladores móviles, SHA-3 está disponible a través de bibliotecas estándar de criptografía a partir de Android 7.0 e iOS 13.
import java.security.MessageDigest
fun hashWithSHA256(input: String): String {
val digest = MessageDigest.getInstance("SHA-256")
val hashBytes = digest.digest(input.toByteArray())
return hashBytes.joinToString("") { String.format("%02x", it) }
}
Los hash criptográficos de propósito general no son suficientes para almacenar contraseñas — son demasiado rápidos. bcrypt está diseñado específicamente para el hashing de contraseñas: incluye una sal y un parámetro de costo que regula el tiempo de cálculo. Duplicar el costo duplica el tiempo de hashing, haciendo que la fuerza bruta sea ineficaz incluso en hardware potente.
import at.favre.lib.crypto.bcrypt.BCrypt
fun hashPassword(password: String): String {
return BCrypt.create()
.hashToString(BCrypt.MIN_COST, password.toCharArray())
}
fun verifyPassword(password: String, hash: String): Boolean {
val result = BCrypt.verifyer().verify(password.toCharArray(), hash)
return result.verified
}
Argon2 es el ganador del Password Hashing Competition (2015), recomendado por OWASP como la mejor opción para el hashing de contraseñas. Argon2id es la variante resistente a ataques de canal lateral y de intercambio tiempo-memoria. A diferencia de bcrypt, Argon2 permite configurar por separado el tiempo de ejecución, el uso de memoria y el grado de paralelismo, proporcionando una protección flexible contra varios tipos de ataques.
El hashing resuelve muchas tareas prácticas en el desarrollo móvil — desde la autenticación de usuarios hasta la verificación de integridad de archivos descargados. Examinemos los casos de uso clave.
El caso de uso principal es el almacenamiento seguro de contraseñas en el lado del servidor. Durante el registro, la aplicación envía la contraseña al servidor, donde se aplica un hash con sal usando bcrypt o Argon2 y se guarda en la base de datos. Durante el inicio de sesión, el servidor aplica hash a la contraseña ingresada y la compara con el hash almacenado. OWASP recomienda usar Argon2id con los parámetros: tiempo 2 segundos, memoria 64 MB, grado de paralelismo 4.
Al descargar archivos grandes como paquetes OBB o actualizaciones de contenido, las aplicaciones móviles pueden verificar su integridad mediante hashing. El servidor publica el hash SHA-256 del archivo, y la aplicación calcula el hash de los datos descargados y los compara. Esto garantiza que el archivo no se haya dañado ni alterado durante la transmisión. Según Google Play Console (2025), la verificación de hash de las aplicaciones certificadas previene hasta el 99.9% de los ataques de descarga corrupta.
Los hash se utilizan activamente para construir cachés eficientes y deduplicación de datos. La dirección de una imagen o respuesta JSON se hashea y se utiliza como clave de caché: en una solicitud repetida, el sistema compara los hash y devuelve el resultado almacenado si los datos no han cambiado. Para esta tarea, son adecuadas las funciones hash no criptográficas como MurmurHash o xxHash, que ofrecen el máximo rendimiento.
import java.security.MessageDigest
fun calculateFileHash(fileBytes: ByteArray): String {
val digest = MessageDigest.getInstance("SHA-256")
val hash = digest.digest(fileBytes)
return hash.joinToString("") { String.format("%02x", it) }
}
fun verifyIntegrity(data: ByteArray, expectedHash: String): Boolean {
val actualHash = calculateFileHash(data)
return actualHash == expectedHash
}
Incluso los desarrolladores experimentados cometen errores al trabajar con hashing. Examinemos los problemas más comunes que pueden anular todos los beneficios de la protección criptográfica.
MD5 y SHA-1 son algoritmos obsoletos para los que existen ataques de colisión prácticos. MD5 fue vulnerado en 2004 por un grupo de investigadores chinos (colisión en una hora). SHA-1 fue vulnerado en 2017 por un equipo de Google y Centrum Wiskunde & Informatica (ataque SHAttered). Usar estos algoritmos en proyectos nuevos se considera un error de seguridad crítico según la clasificación de OWASP.
Aplicar hash a las contraseñas sin sal es una vulnerabilidad crítica. La sal es una cadena aleatoria, única para cada usuario, que se añade a la contraseña antes del hashing. Sin sal, dos contraseñas idénticas producen el mismo hash, lo que permite usar tablas rainbow para el descifrado. OWASP recomienda usar una sal criptográficamente fuerte de al menos 32 bytes, generada por separado para cada usuario.
Incluso al usar bcrypt o Argon2, se puede reducir la protección eligiendo un parámetro de costo demasiado bajo. Según OWASP (2025), el número mínimo de iteraciones de bcrypt debe ser 10 (2^10 = 1024 iteraciones), y para Argon2id, el tiempo de cálculo debe ser de al menos 1 segundo en la plataforma objetivo. Los parámetros demasiado bajos hacen que los ataques de fuerza bruta sean prácticamente factibles en granjas de GPU.
Preguntas frecuentes
El hashing es un proceso unidireccional cuyo resultado no se puede revertir a los datos originales. El cifrado es un proceso bidireccional: los datos cifrados se pueden descifrar usando una clave. El hashing se utiliza para almacenar contraseñas y verificar la integridad, mientras que el cifrado se utiliza para la transmisión confidencial de datos entre el cliente y el servidor.
OWASP recomienda Argon2id como la mejor opción para el hashing de contraseñas debido a su protección configurable contra ataques de GPU y de canal lateral. Alternativas: bcrypt (probado y fácil de configurar), scrypt (resistente a ataques ASIC) y PBKDF2. SHA-256 y SHA-512 no son adecuados para contraseñas — son demasiado rápidos y no protegen contra ataques de fuerza bruta masivos.
Una colisión es una situación en la que dos conjuntos de datos de entrada diferentes producen el mismo hash. Para las funciones hash criptográficas, encontrar colisiones debe ser computacionalmente inviable. Por ejemplo, la probabilidad de una colisión SHA-256 es de aproximadamente 1 entre 2^128 para dos mensajes aleatorios cualesquiera — este es un valor extremadamente pequeño.
No, bcrypt incluye automáticamente la sal en su algoritmo. Al llamar a BCrypt.hashToString(), la biblioteca genera una sal criptográficamente fuerte de 16 bytes y la incrusta en la cadena de salida junto con el hash y el parámetro de costo. scrypt y Argon2 funcionan de manera similar. Esta es una de las razones por las que los expertos recomiendan usar KDF especializados en lugar de funciones hash de propósito general para la protección de contraseñas.
Sí, los hash se utilizan para crear listas blancas y negras de archivos. Las bases de datos de antivirus contienen hash de programas maliciosos conocidos. Sin embargo, los atacantes pueden cambiar un solo byte en un programa, lo que cambia completamente el hash. Por lo tanto, los sistemas modernos utilizan el hashing difuso (SSDeep, TLSH), que encuentra archivos semánticamente similares en lugar de solo coincidencias exactas.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también