Hashes
Los hashes son valores generados a partir de una función hash (un algoritmo), que transforma una entrada (como un texto o archivo) en una cadena en formato hexadecimal de longitud fija. Estas cadenas, llamadas "valores hash" o simplemente "hashes", son únicas para cada entrada, lo que significa que incluso un pequeño cambio en la entrada original resulta en un hash completamente diferente.
Propiedades Importantes de los Hashes:
- Determinismo: La misma entrada siempre genera el mismo hash.
- Rapidez: Las funciones hash son rápidas de calcular.
- Unicidad: Diferentes entradas deben producir diferentes hashes (aunque las colisiones son posibles, son raras en buenas funciones hash).
- Irreversibilidad: Dado un hash, es impracticable reconstruir la entrada original. No debe ser posible que otra función pueda revertir el proceso.
Usos Comunes:
-
Seguridad: Los hashes se utilizan para almacenar contraseñas de forma segura. Por ejemplo, si un usuario está haciendo un registro en tu aplicación y ha introducido la contraseña, no debemos guardar la contraseña directamente en la base de datos. Cualquier persona con acceso a la base de datos o incluso un ataque expondría totalmente las credenciales. Para evitar esto, pasamos la contraseña por una función hash y guardamos el hash en la base de datos. Cuando el usuario vuelva a introducir la contraseña, pásala por la función hash y compárala con el valor que tienes en la base de datos.
- Si guardas la contraseña del usuario en texto plano y esos datos sufren una filtración, el problema puede ser mayor de lo que pensamos. Muchos usuarios utilizan la misma contraseña en muchos lugares y podemos comprometer mucho más que el acceso a una aplicación.
Sabiendo esto, procura siempre usar 2FA en todas tus contraseñas cuando sea posible, nunca uses la misma contraseña y siempre utiliza contraseñas fuertes para evitar ataques de fuerza bruta (intento y error).
-
Integridad de Datos: Verificación de integridad de archivos (como el uso de MD5 o SHA-256 para verificar si un archivo ha sido corrompido o alterado). Si generamos un hash sobre un archivo, este siempre tendrá el mismo hash para la misma función hash aplicada. En el caso de la integridad de archivos podemos usar funciones hash más simples que las usadas en contraseñas.
-
Estructuras de Datos: En estructuras como tablas hash, el hash permite búsquedas rápidas. Esta es otra funcionalidad muy usada en desarrollo y bases de datos, principalmente NoSQL.
-
Criptografía: Los hashes forman parte de muchos algoritmos criptográficos y autenticaciones.
Ejemplos de funciones hash comunes:
- MD5: Genera hashes de 128 bits, pero ya no se considera seguro.
- SHA-1: Genera hashes de 160 bits, pero también tiene vulnerabilidades.
- SHA-256: Parte de la familia SHA-2, es mucho más segura y comúnmente usada hoy en día.
Todavía podemos "añadir sal" al hash pasando una función hash sobre otra para dificultar aún más.
Los algoritmos citados anteriormente fueron diseñados para tener eficiencia y se utilizan principalmente para integridad. Cuando hablamos de hash de contraseñas usado por los programadores, partimos de algoritmos menos eficientes pero mucho más seguros. No ser eficiente en este caso es bueno, porque cuanto más eficiente sea más fuerza daremos al hacker que intentará más veces por segundo romper la contraseña. En este escenario, generalmente los programadores utilizan bcrypt y PBKDF2 justamente por no poder hacer que estos algoritmos sean más rápidos, es parte del diseño de ellos ser más lentos de ejecutar dificultando el trabajo de romper contraseñas. En realidad no son algoritmos de hash sino de derivación de contraseñas, hechos para tomar una contraseña corta o débil e intentar derivar una contraseña más larga y más fuerte.
En resumen, los hashes son fundamentales para varias aplicaciones en tecnología, especialmente donde la seguridad e integridad de los datos son cruciales.
Hashes e Integridad
Vamos a hacer la descarga de Kubernetes. Si miramos en changelogs llegamos a este enlace.
Haz la descarga de uno de los archivos y compara el hash para garantizar la integridad de los archivos. La ventaja de poner todo en un único archivo tar.gz es que podemos pasar el hash sobre él. Copia el enlace y vamos al terminal.
❯ wget https://dl.k8s.io/v1.31.0/kubernetes-server-linux-amd64.tar.gz
--2024-08-20 11:50:02-- https://dl.k8s.io/v1.31.0/kubernetes-server-linux-amd64.tar.gz
Resolving dl.k8s.io (dl.k8s.io)... 34.107.204.206, 2600:1901:0:26f3::
Connecting to dl.k8s.io (dl.k8s.io)|34.107.204.206|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://cdn.dl.k8s.io/release/v1.31.0/kubernetes-server-linux-amd64.tar.gz [following]
--2024-08-20 11:50:02-- https://cdn.dl.k8s.io/release/v1.31.0/kubernetes-server-linux-amd64.tar.gz
Resolving cdn.dl.k8s.io (cdn.dl.k8s.io)... 151.101.93.55, 2a04:4e42:16::311
Connecting to cdn.dl.k8s.io (cdn.dl.k8s.io)|151.101.93.55|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 359694851 (343M) [application/x-tar]
Saving to: 'kubernetes-server-linux-amd64.tar.gz'
kubernetes-server-linux-amd64.tar.gz 100%[===================================================================================================>] 343,03M 3,69MB/s in 94s
2024-08-20 11:51:37 (3,67 MB/s) - 'kubernetes-server-linux-amd64.tar.gz' saved [359694851/359694851]
# Vamos a pasar la misma función hash y comparar los valores. El valor arriba de la imagen es 4d73777e4f139c67c4551c1ca30aefa4782b2d9f3e5c48b8b010ffc329065e90ae9df3fd515cc13534c586f6edd58c3324943ce9ac48e60bb4fa49113a2e09d4
❯ sha512sum kubernetes-server-linux-amd64.tar.gz
4d73777e4f139c67c4551c1ca30aefa4782b2d9f3e5c48b8b010ffc329065e90ae9df3fd515cc13534c586f6edd58c3324943ce9ac48e60bb4fa49113a2e09d4 kubernetes-server-linux-amd64.tar.gz
Podemos entonces confirmar la integridad de nuestros archivos de esta manera.