Hashing con SHA-256 en Criptografía

LinuxBeginner
Practicar Ahora

Introducción

¡Bienvenidos al mundo de la criptografía! En este laboratorio, obtendrá experiencia práctica con uno de los conceptos más fundamentales de la seguridad moderna: el hash criptográfico. Específicamente, trabajaremos con el algoritmo SHA-256.

Una función de hash criptográfico es un algoritmo matemático que toma una entrada (o 'mensaje') de cualquier tamaño y devuelve una cadena de bytes de tamaño fijo. Esta salida es típicamente un 'resumen' o 'hash'. SHA-256, por ejemplo, siempre produce un hash de 256 bits (32 bytes).

Estas funciones tienen varias propiedades importantes:

  • Determinista: La misma entrada siempre producirá la misma salida.
  • Unidireccional (One-way): Es computacionalmente inviable revertir la función y encontrar la entrada original a partir de su hash.
  • Efecto Avalancha (Avalanche Effect): Un pequeño cambio en la entrada (como cambiar un solo carácter) producirá un hash de salida drásticamente diferente.

A lo largo de este laboratorio, utilizará la herramienta de línea de comandos openssl y un script simple de Python para explorar estas propiedades y comprender cómo se utiliza el hashing en escenarios del mundo real, como la verificación de la integridad de archivos y la protección de contraseñas.

Este es un Guided Lab, que proporciona instrucciones paso a paso para ayudarte a aprender y practicar. Sigue las instrucciones cuidadosamente para completar cada paso y obtener experiencia práctica. Los datos históricos muestran que este es un laboratorio de nivel principiante con una tasa de finalización del 93%. Ha recibido una tasa de reseñas positivas del 100% por parte de los estudiantes.

Propiedades de la Función Hash

En este paso, utilizará la herramienta de línea de comandos openssl para explorar dos propiedades fundamentales de las funciones hash: ser deterministas y el efecto avalancha. Una función es determinista si la misma entrada siempre produce la misma salida. El efecto avalancha significa que un cambio minúsculo en la entrada da como resultado un hash de salida completamente diferente.

Primero, generemos un hash SHA-256 para la cadena "hello". Usaremos el comando echo para pasar la cadena a openssl.

echo -n "hello" | openssl dgst -sha256

La opción -n en echo es importante; evita que echo añada un carácter de nueva línea al final de la cadena, lo que cambiaría el hash resultante.

Debería ver una salida como esta:

SHA2-256(stdin)= 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

Ahora, ejecutemos exactamente el mismo comando de nuevo para demostrar la propiedad determinista.

echo -n "hello" | openssl dgst -sha256

Observe que la salida es idéntica. Esto confirma que para la misma entrada, el hash SHA-256 es siempre el mismo.

SHA2-256(stdin)= 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

A continuación, demostraremos el efecto avalancha. Realizaremos un cambio muy pequeño en nuestra cadena de entrada: cambiaremos "hello" por "Hello" (con 'H' mayúscula).

echo -n "Hello" | openssl dgst -sha256

Observe el nuevo hash:

SHA2-256(stdin)= 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969

Compare este hash con el de "hello". Aunque solo se cambió un bit de la entrada (la capitalización de la primera letra), el hash resultante es completamente diferente. Este es el efecto avalancha en acción y es una característica crítica para una función hash segura.

Calcular el Hash de un Archivo

En este paso, calculará el hash SHA-256 de un archivo de texto. Esta es una práctica común utilizada para verificar la integridad de los archivos. Cuando descarga un archivo de Internet, los sitios web a menudo proporcionan una suma de verificación (un hash) para que pueda verificar que el archivo no se corrompió durante la descarga ni fue manipulado.

El script de configuración para este laboratorio ya ha creado un archivo llamado message.txt en su directorio actual (~/project). Primero, veamos su contenido usando el comando cat.

cat message.txt

Verá el siguiente contenido:

This is a secret message.

Ahora, calculemos el hash SHA-256 de este archivo. La sintaxis es similar a la que usó antes, pero en lugar de canalizar (piping) la entrada, proporciona el nombre del archivo como argumento al comando openssl dgst.

openssl dgst -sha256 message.txt

El comando procesará el archivo e imprimirá su hash SHA-256. La salida se verá así:

SHA2-256(message.txt)= 6432f513cfd40d47c8584494c0524468257e50dc1a0422f73becac85189543f8

Este hash sirve como una huella digital única para el contenido actual de message.txt. Si alguien cambia incluso un solo carácter en el archivo, el hash cambiará por completo, como verá en un paso posterior.

Generar Múltiples Hashes

En este paso, practicarás más la generación de hashes SHA-256 para diferentes entradas de cadena (string). Esto ayudará a reforzar tu comprensión de cómo cualquier entrada única produce un hash único. Continuaremos usando el comando echo -n canalizado (piped) a openssl para asegurar que solo estamos hasheando la cadena en sí, sin caracteres adicionales.

Primero, generemos el hash para la cadena "labex".

echo -n "labex" | openssl dgst -sha256

La salida será el hash SHA-256 para "labex":

SHA2-256(stdin)= 679e75b679886c5eaf8aaab88ddfc0181e6dae14cff346db8ba398bd7b2e31fe

A continuación, probemos una cadena diferente, "crypto", para ver su hash único.

echo -n "crypto" | openssl dgst -sha256

Como se esperaba, esto produce un hash completamente diferente:

SHA2-256(stdin)= da2f073e06f78938166f247273729dfe465bf7e46105c13ce7cc651047bf0ca4

Este ejercicio demuestra que cada fragmento de datos distinto, sin importar cuán pequeño o grande sea, tiene su propio valor hash único. Esta propiedad es fundamental para cómo se utilizan los hashes para la verificación de datos, en tecnologías blockchain y en firmas digitales.

Demostrar Resistencia a Colisiones

En este paso, observará directamente el efecto avalancha y el concepto de resistencia a colisiones modificando ligeramente el archivo message.txt y viendo cómo cambia su hash. La resistencia a colisiones significa que es extremadamente difícil encontrar dos entradas diferentes que produzcan el mismo hash.

Primero, recalculemos el hash del archivo original message.txt para tenerlo fresco en nuestra memoria.

openssl dgst -sha256 message.txt

Debería ver el hash original de nuevo:

SHA2-256(message.txt)= 6432f513cfd40d47c8584494c0524468257e50dc1a0422f73becac85189543f8

Ahora, hagamos un cambio muy pequeño en el archivo. Agregaremos un solo punto (.) al final del archivo. Podemos hacer esto fácilmente usando el comando echo con el operador de redirección >>, que adjunta la salida a un archivo.

echo "." >> message.txt

Puede verificar que el cambio se realizó viendo el contenido del archivo nuevamente.

cat message.txt

Verá el punto al final:

This is a secret message.
.

Ahora, recalculemos el hash del archivo modificado.

openssl dgst -sha256 message.txt

El nuevo hash será:

SHA2-256(message.txt)= 4106e1c985a4ee1754fff76b8bffda0c4844679885cb70758f24cd43e771daac

Compare este nuevo hash con el original. Son completamente diferentes. Esta poderosa demostración muestra que incluso un cambio de un solo carácter en un archivo resultará en un hash radicalmente diferente, lo que facilita la detección de cualquier forma de manipulación.

Crear Hash de Contraseña

En este paso, pasará de la línea de comandos a escribir un script simple de Python para hashear una contraseña. Almacenar contraseñas en texto plano es una vulnerabilidad de seguridad importante. La práctica estándar es almacenar un hash de la contraseña en su lugar. Cuando un usuario intenta iniciar sesión, el sistema hashea la contraseña que ingresó y la compara con el hash almacenado.

El script de configuración ya ha creado un archivo vacío llamado hash_password.py. Ahora agregará código a él usando el editor de texto nano.

Abra el archivo con nano:

nano hash_password.py

Ahora, copie y pegue el siguiente código Python en el editor nano:

import hashlib

## The password we want to hash
password = "mysecretpassword"

## Hash functions in Python work on bytes, not strings.
## We must encode the string into bytes first, using UTF-8.
password_bytes = password.encode('utf-8')

## Create a new SHA-256 hash object.
sha256_hash = hashlib.sha256(password_bytes)

## Get the hexadecimal representation of the hash.
hex_digest = sha256_hash.hexdigest()

print(f"The password is: {password}")
print(f"The SHA-256 hash is: {hex_digest}")

Este script realiza lo siguiente:

  1. Importa la librería hashlib, que proporciona varios algoritmos de hashing.
  2. Define una cadena de contraseña (password string).
  3. Codifica la cadena a bytes usando .encode('utf-8'). Este es un paso crucial, ya que las funciones hash operan sobre bytes.
  4. Crea un objeto hash SHA-256 y lo actualiza con los bytes de la contraseña.
  5. Recupera el hash final en un formato hexadecimal legible usando .hexdigest().

Después de pegar el código, guarde el archivo y salga de nano presionando Ctrl+X, luego Y, y finalmente Enter.

Finalmente, ejecute su script de Python desde la terminal:

python3 hash_password.py

El script se ejecutará e imprimirá la contraseña y su hash SHA-256 correspondiente:

The password is: mysecretpassword
The SHA-256 hash is: 94aefb8be78b2b7c344d11d1ba8a79ef087eceb19150881f69460b8772753263

Ha utilizado con éxito Python para realizar hashing criptográfico, una habilidad esencial para el desarrollo seguro de aplicaciones.

Resumen

¡Felicidades por completar este laboratorio! Ha adquirido experiencia práctica y directa con la función hash criptográfica SHA-256.

En este laboratorio, aprendió:

  • Las propiedades fundamentales de las funciones hash: son deterministas, de un solo sentido (one-way) y exhiben el efecto avalancha (avalanche effect).
  • Cómo usar el comando openssl dgst -sha256 en un entorno Linux para calcular hashes tanto para cadenas de texto como para archivos.
  • La importancia del hashing para verificar la integridad de archivos (file integrity) y detectar manipulaciones.
  • Cómo usar la librería hashlib de Python para generar hashes SHA-256 mediante programación, una tarea común en la seguridad de contraseñas (password security).

El hashing es una piedra angular de la ciberseguridad moderna. Las habilidades que ha practicado aquí son fundamentales para comprender temas más avanzados como firmas digitales, códigos de autenticación de mensajes (MACs) y tecnología blockchain. Como siguiente paso, podría investigar sobre el "salting" de contraseñas, que añade otra capa de seguridad sobre el hashing.