Contraseña vs UUID vs Hash vs Token: Guía de 8 tipos de cadenas aleatorias para desarrolladores

En el desarrollo de software, te encuentras constantemente con cadenas como 550e8400-e29b-41d4-a716-446655440000 o eyJhbGciOiJIUzI1NiJ9... — secuencias de caracteres de aspecto aleatorio. UUID, contraseñas, hashes, tokens, claves de API… todas se parecen, pero su intención de diseño y su propósito son fundamentalmente distintos.

Este artículo desglosa los 8 tipos más comunes de cadenas de aspecto aleatorio desde la perspectiva de «por qué existen» y «qué protegen». Una vez que entiendes qué es realmente cada una, elegir la adecuada para cada situación se vuelve algo natural.

Comparación de los 8 tipos

Empecemos por la visión general.

TipoUso principal¿Secreto?¿Reversible?GeneraciónRasgo clave
UUIDIdentificación únicaNoAleatorio / tiempoID sin colisión
ContraseñaAutenticación de usuarioSolo el propietarioCreada por humanoSecreto memorizado
HashVerificación de integridadNoIrreversibleFunción matemáticaHuella digital
TokenAutenticación / autorizaciónDependeCSPRNGCaduca
Clave de APIAutenticación de servicioCSPRNGContraseña de máquina
Sal (Salt)Refuerzo del hashNoCSPRNGDefensa anti rainbow table
NonceIdentificación de un solo usoNoCSPRNGPrevención de repetición
FirmaDetección de manipulaciónNoIrreversibleCálculo criptoHMAC, firma RSA

La idea esencial: clasifica por propósito de diseño, no por apariencia. La misma cadena aleatoria de 32 caracteres puede ser una mera etiqueta cuando se usa como UUID, o una clave de autenticación cuando se usa como token.

UUID — Una etiqueta sin colisiones

Un UUID (Universally Unique Identifier) existe para generar identificadores que no colisionen — en cualquier parte del mundo, sin coordinación. No tiene nada que ver con la seguridad; su única función es la identificación.

La variante más utilizada, el UUID v4, se genera de forma aleatoria con 122 bits de entropía. Eso equivale a unos 5,3 × 1036 valores posibles — incluso generando mil millones por segundo, esperarías más de 10 000 millones de años para una colisión.

Casos de uso comunes:

  • Claves primarias de bases de datos (alternativa al autoincremento)
  • IDs de objetos únicos en sistemas distribuidos
  • Nombres de archivo sin colisión para las subidas
  • IDs de petición para trazado y registro (logging)
💡 Consejo

el UUID v1 incrusta una marca de tiempo y una dirección MAC, lo que hace adivinables el momento de generación y el dispositivo. Usa el v4 (totalmente aleatorio) para IDs visibles externamente. Y nunca reutilices un UUID como clave de sesión o token — los UUID garantizan «sin colisiones», no «sin adivinación».

Prueba y aprende con nuestro generador de UUID gratuito

Contraseña — El único secreto gestionado por humanos

Entre los 8 tipos, las contraseñas son las únicas diseñadas para la memorización humana. Esto hace que su entropía dependa intrínsecamente de la memoria humana — y, por tanto, sea más débil que las alternativas generadas por máquina.

Precisamente por eso las contraseñas necesitan un trato especial para su almacenamiento. Guardarlas en texto plano es inaceptable. Deben hashearse, y no con cualquier hash — la buena práctica moderna exige algoritmos deliberadamente lentos como bcrypt, Argon2 o scrypt.

¿Por qué importa que sea «lento»? Cuando un atacante intenta miles de millones de cálculos de hash por segundo en un ataque de fuerza bruta, un algoritmo que tarda 0,1 segundos por cálculo aumenta el coste del ataque en varios órdenes de magnitud.

Casos de uso comunes:

  • Autenticación de inicio de sesión en servicios web
  • Credenciales de acceso a SSH y bases de datos
  • Frases de contraseña de cifrado para archivos
💡 Consejo

la fortaleza de una contraseña se determina por conjunto de caracteres × longitud. Una corta P@ssw0rd con símbolos es mucho más débil que una frase de contraseña larga como correct horse battery staple. Usa siempre un gestor de contraseñas.

Prueba y aprende con nuestro generador de contraseñas gratuito

Hash — Una huella digital

Una función hash toma una entrada de cualquier longitud y produce una salida de longitud fija — una transformación de un solo sentido. La misma entrada siempre da la misma salida, pero no puedes revertirla. Piénsalo como la huella digital de un dato.

Por ejemplo, SHA-256 comprime tanto un «hello» de 5 caracteres como un archivo de 1 GB en un valor de 256 bits (64 caracteres hexadecimales). Cambia un solo bit del dato original y el hash cambia por completo.

Casos de uso comunes:

  • Almacenamiento de contraseñas — Guardar el hash en lugar del texto plano
  • Comprobación de integridad de archivos — Verificar que las descargas no se hayan manipulado (checksums)
  • IDs de commit de Git — Git gestiona cada commit con hashes SHA-1
  • Blockchain — Las cadenas de transacciones se aseguran con hashes
💡 Consejo

MD5 y SHA-1 tienen ataques de colisión prácticos — no los uses para seguridad. Elige SHA-256 o superior en proyectos nuevos. Para almacenar contraseñas, no uses SHA en absoluto — es «demasiado rápido», lo que lo hace vulnerable a la fuerza bruta. Usa bcrypt o Argon2 en su lugar.

Prueba y aprende con nuestro generador de hash gratuito

Token — Un pase temporal

Un token demuestra que «esta persona está autenticada» — temporalmente. Tras un inicio de sesión correcto, el servidor emite un token; las peticiones siguientes incluyen ese token para afirmar «ya estoy autenticado».

El ejemplo más famoso es el JWT (JSON Web Token), compuesto por tres partes codificadas en Base64: cabecera, payload y firma. El payload contiene el ID de usuario y la caducidad, y la firma detecta manipulaciones.

Casos de uso comunes:

  • Gestión de sesiones de aplicaciones web
  • Tokens de acceso y de actualización (refresh) de OAuth 2.0
  • Enlaces de un solo uso para verificación de correo y restablecimiento de contraseña
  • Autenticación sin estado (stateless) en SPAs
💡 Consejo

los payloads de JWT están codificados en Base64 — no cifrados — así que cualquiera puede leer el contenido. Nunca pongas contraseñas ni números de tarjeta de crédito en un JWT. Mantén corta la vida de los tokens de acceso (15 minutos a 1 hora) y usa tokens de actualización para la renovación.

Prueba y aprende con nuestro generador de tokens gratuito

Clave de API — Una contraseña para máquinas

Una clave de API es una cadena que permite a una aplicación o servicio decir «soy un usuario autorizado». No la teclea un humano — va incrustada en el código y se adjunta a las peticiones.

La mayor diferencia con las contraseñas: nadie necesita recordarla. Esto permite generar cadenas aleatorias suficientemente largas (128–256 bits), lo que las hace mucho más fuertes. La contrapartida es que a menudo quedan en texto plano en el código fuente o en archivos de configuración, creando un alto riesgo de filtración.

Casos de uso comunes:

  • Autenticación de APIs externas (Google Maps, OpenAI, Stripe)
  • Autenticación interna de servicio a servicio en microservicios
  • Identificación para facturación y límite de tasa (rate limit)
💡 Consejo

subir sin querer claves de API a GitHub es un problema recurrente. Guárdalas en archivos .env o variables de entorno y añade .env al .gitignore — esto es innegociable. El Secret Scanning de GitHub puede revocar automáticamente algunas claves, pero no confíes en él como única protección.

Prueba y aprende con nuestro generador de claves de API y tokens gratuito

Sal, Nonce y Firma — Los especialistas entre bastidores

Estos tres rara vez aparecen solos — son componentes que refuerzan otros mecanismos.

Sal (Salt)

Una sal es un valor aleatorio que se añade por usuario al hashear contraseñas. Aunque dos usuarios compartan la contraseña «password123», sales distintas producen hashes distintos. Esto derrota los ataques de rainbow table — diccionarios de hashes precalculados.

Las sales no necesitan ser secretas — se almacenan junto al hash en la base de datos. Los algoritmos modernos como bcrypt y Argon2 gestionan la generación y el manejo de la sal internamente, por lo que los desarrolladores rara vez tienen que ocuparse de ello manualmente.

Nonce

Nonce significa «Number used ONCE» — un valor desechable. Su propósito principal es la prevención de ataques de repetición (replay). Si un atacante intercepta y reenvía una petición, el servidor reconoce que el nonce ya se usó y la rechaza.

En el desarrollo web, los nonces también se usan como tokens de protección CSRF (Cross-Site Request Forgery). La función wp_nonce_field() de WordPress es un ejemplo bien conocido.

Firma

Una firma demuestra que unos datos no se han manipulado. HMAC (Hash-based Message Authentication Code) combina una clave secreta con un mensaje para calcular un hash. Sin la clave secreta, un tercero no puede producir una firma válida — así, el receptor puede confirmar que los datos provienen de un remitente legítimo.

El alg: HS256 en una cabecera JWT significa «firmado con HMAC-SHA256». Los webhooks de API (Stripe, GitHub, etc.) también usan firmas HMAC para detectar manipulaciones en el cuerpo de la petición.

Organizar por ejes de diseño

En lugar de memorizar cada tipo individualmente, organízalos a lo largo de 5 ejes.

Tipo¿Secreto?¿Recuperable?¿Unicidad crítica?¿Caduca?¿Uso humano?
UUID××××
Contraseña◎ (solo el propietario)×
Hash×× (irreversible)××
Token×
Clave de API××
Sal××××
Nonce×××
Firma×× (irreversible)×

Fíjate en que solo las contraseñas tienen ◎ en «Uso humano». Esto resalta hasta qué punto las contraseñas son un caso fundamentalmente especial entre todos estos tipos de cadena.

Pensar en modelos de ataque

En el diseño de seguridad, la pregunta que guía no es «¿qué protegemos?», sino «¿qué ataque prevenimos?«. Cada tipo de cadena se enfrenta a una amenaza distinta.

TipoAtaque a prevenirEstrategia de defensa
UUIDColisión (IDs duplicados)Entropía suficiente para hacer las colisiones insignificantes
ContraseñaFuerza bruta / diccionarioHash lento + sal + contraseñas largas
HashAtaque de preimagen / colisiónUsar algoritmos seguros (SHA-256+)
TokenRepetición / interceptaciónTTL corto + HTTPS + rotación de refresh
Clave de APIFiltraciónVariables de entorno + rotación + restricciones de IP
NonceRepeticiónUn solo uso + seguimiento en el servidor
FirmaManipulaciónGestión estricta de la clave secreta

No necesitas resistencia a la fuerza bruta para los UUID, y rara vez te preocupa la resistencia a colisiones en las contraseñas. Amenazas distintas exigen diseños distintos.

Un flujo de decisión práctico

Cuando dudes sobre qué tipo usar, sigue este razonamiento:

  1. Define el propósito — ¿Identificación? ¿Autenticación? ¿Verificación? ¿Temporal?
  2. Identifica la amenaza — ¿Colisión? ¿Adivinación? ¿Filtración? ¿Repetición? ¿Manipulación?
  3. Determina la entropía necesaria — 122 bits para UUID, 256 bits para tokens
  4. Elige el método de generaciónMath.random() nunca es aceptable; usa módulos crypto
  5. Decide el almacenamiento — ¿Texto plano? ¿Hasheado? ¿Cifrado? ¿Variable de entorno?

El punto 4 es crucial. Los generadores aleatorios estándar (Math.random(), random.random()) no son criptográficamente seguros. Para cualquier cadena relacionada con la seguridad, usa siempre un CSPRNG (generador de números pseudoaleatorios criptográficamente seguro). En Python, es el módulo secrets; en Node.js, crypto.randomBytes().

Resumen

Agrupados por propósito de diseño, los 8 tipos se dividen en 4 categorías:

  • Identificación: UUID
  • Autenticación: Contraseña, Clave de API
  • Verificación: Hash, Firma
  • Autenticación temporal / defensa: Token, Nonce, Sal

Pueden parecer idénticas, pero su propósito de diseño es completamente distinto — ese es el mensaje central de este artículo.

Como desarrollador, adopta este principio: «No mires la cadena — mira el propósito.» Ya estés diseñando una nueva cadena aleatoria o trabajando con una existente, pregúntate siempre primero «¿qué protege esto?». El método de generación, el enfoque de almacenamiento y la política de caducidad correctos se derivarán de forma natural.

Comments

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *