Saltar al contenido
Nuevo

DeepSeek V4.1 Flash gratis por 7 días: 10M tokens al día tras cualquier recarga. Hasta el 30/11.

Cómo funciona

Cifrado, codificación y hash: diferencias explicadas

Separa codificación, cifrado y hash con laboratorios de Base64, SHA-256 y OpenSSL. Entiende por qué Base64 no protege y el hash es de un solo sentido.

Principiante10 min de lecturaPor NotHoly

Codificación, cifrado y hash transforman los datos en otra cosa, y por eso se confunden. Tienen objetivos distintos. La codificación cambia la forma en que se escriben los datos, así que cualquiera puede revertirla. El cifrado oculta los datos a quien no tiene una clave, y se revierte con esa clave. El hash produce una huella corta que no se puede convertir de nuevo en la entrada original. Si recuerdas una sola frase: Base64 no es cifrado, y un hash no oculta nada en entradas cortas.

Este artículo separa las tres ideas y te pide ejecutar cada una en la terminal con el mismo texto. Así comparas los resultados tú mismo.

Antes de empezar

Necesitas una terminal con base64, sha256sum y openssl. En Windows 11, los comandos de abajo se ejecutan en Git Bash, que viene con Git para Windows. Incluyo también una versión en PowerShell para el paso del hash. No necesitas conocimientos previos de criptografía, aunque leer antes el artículo sobre el cifrado César ayuda a entender la idea de clave.

Todos los comandos del laboratorio son seguros de ejecutar en tu equipo. Usa un archivo de prueba, no un secreto real.

Tres trabajos distintos

Las tres operaciones responden a tres preguntas diferentes.

Operación Pregunta que responde ¿Necesita clave? ¿Se puede revertir?
Codificación ¿Cómo represento estos bytes como texto o en un formato que otro sistema espera? No Sí, por cualquiera
Cifrado ¿Quién puede leer estos datos? Sí Sí, quien tenga la clave correcta
Hash ¿Estos datos cambiaron, o dos valores coinciden? No No, por diseño

Ten esta tabla presente durante el laboratorio. El resto del artículo explica cada fila.

La codificación cambia la representación

La codificación reescribe los datos en otra forma para que un sistema pueda transportarlos. Base64 es el ejemplo clásico. Toma bytes y los escribe con 64 caracteres imprimibles: A a Z, a a z, 0 a 9, + y /, usando = como relleno. La RFC 4648 define el formato. Los adjuntos de correo, las data URLs y muchos payloads de API lo usan porque el canal espera texto.

Base64 no tiene ningún secreto. La tabla de conversión es pública y fija. Cualquier herramienta que conozca la regla puede convertir la salida otra vez en la entrada. Ese es el propósito de la codificación: interoperar, no mantener algo en secreto.

El cifrado oculta los datos tras una clave

El cifrado toma datos legibles, llamados texto plano, y los transforma con un algoritmo y una clave en texto cifrado. Quien no tiene la clave no debería obtener nada útil del texto cifrado. Quien tiene la clave puede descifrarlo.

Hay dos familias. El cifrado simétrico usa la misma clave secreta para cifrar y descifrar. AES es la opción más común. El cifrado asimétrico usa una clave pública y una privada. Este artículo usa cifrado simétrico, porque el comando de OpenSSL del laboratorio también lo hace.

Un cifrado bueno depende de algo más que del algoritmo. Hay que elegir un modo seguro, generar las claves con una fuente aleatoria confiable y proteger la clave. El comando de OpenSSL del laboratorio usa una contraseña y PBKDF2 para derivar la clave. El texto de ayuda de OpenSSL indica que PBKDF2 usa 10.000 iteraciones por defecto, salvo que cambies ese valor con -iter.

El hash crea una huella

Una función hash criptográfica recibe una entrada de cualquier longitud y devuelve una salida de longitud fija. SHA-256 está especificado en la FIPS 180-4, y su salida siempre tiene 256 bits, escritos como 64 caracteres hexadecimales. Dos propiedades importan para quien empieza:

  • La misma entrada siempre produce la misma salida.
  • Un cambio pequeño en la entrada debe alterar la salida de forma que parezca no relacionada. Las buenas funciones hash están diseñadas para que encontrar dos entradas con la misma salida sea inviable.

El hash es de un solo sentido. Nada en la salida muestra el texto original. Puedes comprobar si una entrada candidata produce un hash conocido. No puedes recuperar la entrada solo a partir del hash, salvo adivinando y probando.

Recuerda que un hash es una huella, no un candado. Cualquiera puede calcular el SHA-256 de un archivo público. El hash demuestra que dos copias son iguales. No oculta el archivo.

Por qué importa

La mayoría de los errores de seguridad reales en esta área vienen de usar la herramienta equivocada para el trabajo.

  • Un desarrollador guarda una clave de API en Base64 y la llama "cifrada". Quien vea el valor la decodifica con un comando.
  • Un equipo verifica una descarga con un hash, pero el hash se publica en la misma página que el archivo, servida por el mismo servidor comprometido. La comprobación solo demuestra que el archivo coincide con la página, nada más.
  • Una aplicación web guarda contraseñas con SHA-256 puro. Una base de datos robada puede atacarse con suposiciones rápidas, porque SHA-256 fue diseñado para ser rápido. La guía de OWASP sobre almacenamiento criptográfico dice que las contraseñas deben protegerse con algoritmos seguros de hash de contraseñas en lugar de cifrado reversible, y remite a su Password Storage Cheat Sheet para los detalles. Las opciones habituales son funciones lentas y con sal, como Argon2id, scrypt, bcrypt o PBKDF2. El siguiente artículo de esta serie trata sobre Argon2id.

Entender esta diferencia desde el principio te evita estas trampas.

Laboratorio 1: codificar con Base64

Abre Git Bash en una carpeta vacía. Codifica una frase corta y luego decodifica el resultado.

bash
echo -n 'hello lab' | base64

La salida que obtuve en este equipo, con OpenSSL 3.2.4 y Git Bash:

text
aGVsbG8gbGFi

Ahora decodifica esa salida:

bash
echo -n 'aGVsbG8gbGFi' | base64 -d

Salida:

text
hello lab

Dos cosas para notar. Primero, no intervino ninguna clave. Segundo, echo -n importa. Sin -n, echo añade un salto de línea y la salida en Base64 cambia. Ejecuta echo 'hello lab' | base64 y compara: obtuve aGVsbG8gbGFiCg==. Aquí Base64 convierte 9 bytes en 12 caracteres, así que la salida es más larga que la entrada.

Pregúntate: ¿alguien sin ningún secreto podría revertir esto? Sí. Esa es la prueba que separa la codificación del cifrado.

Laboratorio 2: hash con SHA-256

Pasa la misma frase por SHA-256:

bash
echo -n 'hello lab' | sha256sum

Salida:

text
8fc6baba79a0d60b37dee612ccc1ec096ef52dba8cb0a24a6451e8bfb0e4d761 *-

Ahora añade un signo de exclamación y vuelve a ejecutarlo:

bash
echo -n 'hello lab!' | sha256sum

Salida:

text
36902fb7fdea33458ad09dfeb52118dc47f99a8ca2b9001080366d55511de915 *-

Los dos hashes no comparten ningún patrón visible. Un solo carácter cambió toda la salida. Ambos tienen 64 caracteres hexadecimales, es decir, 256 bits.

El - al final indica que la entrada vino de la entrada estándar, no de un archivo. El * anterior es la marca de modo binario que imprime el sha256sum de Git Bash. Otros sistemas pueden imprimir dos espacios, y el hash es el mismo. El hash de un archivo funciona igual.

Calcula el hash de un archivo y detecta un cambio

Crea un archivo pequeño y calcula su hash:

bash
echo 'secret note' > note.txt
sha256sum note.txt

En mi equipo, con saltos de línea estilo Unix en el archivo, la salida fue:

text
b5f891a5e064fec661025d0b0ec2de157487a6c2e5cc46dc0971fee56f86c645 *note.txt

Cambia el archivo, aunque sea un solo carácter, y vuelve a calcular el hash. El valor será otro. Así funcionan las comprobaciones de integridad. La comprobación te dice que el archivo cambió. No te dice qué cambió, y no impide que un atacante modifique el archivo y el hash publicado a la vez.

Alternativa en PowerShell de Windows

Si prefieres PowerShell, Windows tiene un comando integrado:

powershell
Get-FileHash note.txt -Algorithm SHA256

Busca en la salida la línea Hash, que muestra 64 caracteres hexadecimales. El hash depende de los bytes exactos del archivo. Set-Content de PowerShell escribe saltos de línea de Windows (CRLF), que son distintos del final LF del ejemplo de Bash. En mi equipo, un archivo escrito así dio este hash:

text
406A5646AE75CA75D032F306ABD33085DC9F656E3109BB962AEAB335EEC9ED85

Los mismos bytes calculados con sha256sum en Git Bash dieron el mismo valor, en minúsculas. Si tu hash difiere del ejemplo de Bash pero coincide con el resultado de PowerShell para tu propio archivo, la causa son los saltos de línea.

Laboratorio 3: cifrar un archivo con OpenSSL

Crea una nota y cífrala con AES-256-CBC. OpenSSL te pedirá una contraseña. Elige una que recuerdes y úsala solo en este laboratorio.

bash
echo 'secret note' > note.txt
openssl enc -aes-256-cbc -pbkdf2 -salt -in note.txt -out note.enc

OpenSSL pide la contraseña y el archivo cifrado se escribe en note.enc. La opción -salt añade una sal aleatoria, así que cifrar el mismo archivo dos veces produce salidas distintas. Un archivo cifrado con -salt empieza con el texto ASCII Salted__. Lo comprobé en mi equipo. El resto del archivo es binario e ilegible.

Ahora descífralo:

bash
openssl enc -d -aes-256-cbc -pbkdf2 -in note.enc

Introduce la misma contraseña. Salida:

text
secret note

El descifrado solo funciona con la contraseña correcta. Probé con una incorrecta. OpenSSL mostró bad decrypt y terminó con error.

El cifrado por sí solo no detecta manipulaciones

Después, cambia un byte del archivo cifrado e intenta descifrarlo. Invertí un bit dentro del bloque cifrado de una copia llamada tampered.enc. El descifrado falló con bad decrypt, y el comando terminó con estado 1.

Ese fallo es una casualidad del relleno del modo CBC. Otros cambios pueden producir basura sin ningún error. La lección es que el cifrado simple no da una señal fiable de que el texto cifrado fue modificado. Los sistemas que necesitan confidencialidad e integridad a la vez usan cifrado autenticado, como AES-GCM, o añaden un código de autenticación de mensajes. Es un tema avanzado, pero explica por qué un archivo cifrado no es automáticamente un archivo de confianza.

Las tres, lado a lado

Pasa el mismo texto por cada operación y compara:

Operación Comando Salida para hello lab (observada)
Codificación echo -n 'hello lab' | base64 aGVsbG8gbGFi
Hash echo -n 'hello lab' | sha256sum 8fc6baba...e4d761
Cifrado openssl enc ... -in note.txt Datos binarios, necesitas la contraseña para leerlos

Pregúntate qué te permite hacer cada salida:

  • Base64 permite que cualquiera recupere hello lab.
  • El hash permite verificar que una entrada candidata es hello lab, pero no recuperar la entrada solo a partir del hash.
  • El archivo cifrado permite recuperar secret note solo con la contraseña.

Errores comunes

Llamar "cifrado" u "ofuscación" a Base64 para secretos. Base64 no oculta nada. Quien vea una cadena en Base64 puede decodificarla. Guarda los secretos en un gestor de secretos o en un almacén cifrado, no en forma codificada.

Usar un hash como candado. Un hash es de un solo sentido, pero las entradas cortas o comunes se pueden adivinar. Calcula el hash de hello lab y un atacante con una lista de frases comunes lo recupera sin romper SHA-256. Por eso el hash de contraseñas necesita sal y algoritmos lentos.

Usar SHA-256 puro para contraseñas. SHA-256 es rápido por diseño, lo que sirve para sumas de verificación de archivos y no sirve para almacenar contraseñas. Usa una función de hash de contraseñas hecha para ese fin.

Confiar en un hash que viene del mismo lugar que el archivo. Un checksum en la misma página comprometida no demuestra nada. Obtén el hash esperado por un canal separado y confiable, o verifica una firma digital.

Olvidar que el cifrado exige gestión de claves. El laboratorio usa una contraseña escrita en un prompt. Los sistemas reales deben almacenar, rotar y proteger las claves. Perder la clave significa perder los datos.

Escribir tu propia criptografía. Usa bibliotecas y protocolos establecidos. Los comandos del laboratorio sirven para aprender, no son una plantilla para sistemas de producción.

Cómo seguir

Repite los tres laboratorios con otra frase y después con un archivo de unos pocos kilobytes. Verás que la salida en Base64 crece alrededor de un tercio, que el hash sigue teniendo 64 caracteres y que el archivo cifrado crece solo por la cabecera y el relleno.

Después, lee sobre hash de contraseñas. El problema allí no es el hash en sí, sino el costo de adivinar. El siguiente artículo de la serie, Cómo funciona el hash de contraseñas con Argon2id, explica la sal, el factor de trabajo y por qué importan los hashes lentos. Si antes quieres repasar el lado de las cifras, lee Cifrado César en Python. Muestra una clave y un algoritmo en una forma que puedes probar.

Cuando estudies protocolos reales, busca tres cosas en cada diseño: qué codifica, qué cifra y qué calcula como hash. La mayor parte de la confusión desaparece cuando preguntas cuál de los tres trabajos está haciendo cada parte.

Fuentes

Fuentes

  1. RFC 4648: The Base16, Base32, and Base64 Data Encodings
  2. FIPS 180-4: Secure Hash Standard (SHS), with update 1
  3. OWASP Cryptographic Storage Cheat Sheet

Más en Criptografía

Criptografía

Contraseñas y hash con Argon2id

Por qué los hashes rápidos fallan con contraseñas, qué hacen la sal y el factor de trabajo, y cómo hashear y verificar con Argon2id en Python.

Intermedio11 min de lectura