Generador de tokens

Genera secretos con el generador criptográfico del navegador — hex, base64url o un alfabeto propio, y frases de contraseña EFF — con entropía en bits.

Generando…
Entropía192.0 bits

Tiempo medio para encontrarlo, a tres velocidades de adivinación. La diferencia entre ellas es mayor que cualquiera que marque el secreto mismo.

  • Contra un acceso con límite de intentos — 10 intentos/s10^49 años
  • Contra un hash lento filtrado (bcrypt, argon2) — 10⁴/s10^46 años
  • Contra un hash rápido filtrado (SHA-256, MD5) — 10¹²/s10^38 años

Se extrae de 64 caracteres, así que cada uno lleva 6.00 bits.

Qué hace esta herramienta

Produce secretos: valores cuya única defensa es que nadie pueda adivinarlos. Elige un alfabeto y una longitud para una clave de API o una contraseña de base de datos, o cambia a una frase de contraseña extraída de una lista publicada para algo que una persona tenga que teclear. Cada resultado se genera en tu navegador y se muestra con el único número que describe su fuerza con honestidad.

Es un trabajo distinto del generador de UUID de este sitio. Un UUID tiene que ser único, para que dos registros nunca choquen; un secreto tiene que ser inadivinable, que es un requisito más fuerte y un fallo distinto. Un identificador predecible es inofensivo. Un secreto predecible es una puerta abierta.

De dónde viene la aleatoriedad

Todo aquí se extrae de crypto.getRandomValues, el generador de aleatoriedad criptográficamente seguro del navegador, sembrado desde el fondo de entropía del sistema operativo: la misma fuente que usan openssl rand y /dev/urandom.

La alternativa, Math.random, no es una función de seguridad y nunca ha pretendido serlo. Es un generador pseudoaleatorio rápido con un estado interno pequeño, y en todos los motores actuales ese estado puede recuperarse a partir de una tirada corta de salidas, tras lo cual todos los valores pasados y futuros son conocidos. Un token construido con él parece exactamente tan aleatorio como uno de verdad; la diferencia solo aparece cuando alguien se molesta en mirar.

Una pregunta razonable es si una página web es el sitio adecuado para generar un secreto de producción. La generación en sí es sólida: es el CSPRNG de la plataforma, la página es estática y nada se transmite. Lo que conviene pensar es lo que la rodea: un secreto que pasa por el portapapeles puede ser legible para otras aplicaciones, y uno pegado en un terminal suele acabar en el historial del intérprete. Son las mismas consideraciones que con cualquier otro método.

El sesgo escondido en la implementación obvia

Convertir bytes aleatorios en caracteres parece una sola línea: coge un byte, aplícale el módulo del tamaño del alfabeto e indexa. Es sutilmente incorrecto para todo alfabeto cuyo tamaño no divida 256 de forma exacta, y la salida no da ninguna señal de ello.

Con 62 caracteres alfanuméricos, 256 no se divide de forma exacta: 62 cabe en 256 cuatro veces y sobran 8. Esos 8 valores de byte sobrantes —del 248 al 255— se pliegan sobre los primeros 8 caracteres del alfabeto, así que cada uno de ellos recibe cinco oportunidades entre 256 mientras el resto reciben cuatro. Los primeros ocho caracteres son un 25% más probables que los demás.

La solución es el muestreo con rechazo: descartar una extracción que caiga en la cola sobrante y volver a extraer, en lugar de plegarla hacia dentro. Cuesta cerca de una extracción extra de cada treinta y dos para un alfabeto de 62 caracteres y nada en absoluto para hex o base64url, cuyos tamaños son potencias de dos y por tanto no tienen cola. Esta herramienta rechaza; el efecto no se ve en ningún token concreto, que es justamente por lo que merece decirse.

La entropía, que es la única medida honesta

La entropía en bits dice cuán grande es el espacio de secretos igualmente probables: n bits significan 2^n posibilidades. Es aditiva y fácil de comparar, y no dice nada sobre lo rápido que alguien puede recorrer ese espacio, lo cual es una virtud, porque esa parte depende de cosas que un generador no puede saber.

La aritmética es deliberadamente sencilla. Cada carácter aporta log2(tamaño del alfabeto) bits, y cada palabra aporta log2(tamaño de la lista), de modo que:

  • Un carácter hex son 4 bits, así que un token hex de 32 caracteres son exactamente 128 bits: una clave AES-128 escrita por extenso.
  • Un carácter base64url son 6 bits, así que 22 caracteres pasan de 128 bits y 43 pasan de 256.
  • Un carácter alfanumérico son unos 5,95 bits; excluir los parecidos baja el alfabeto a 58 y el carácter a 5,86, lo que cuesta aproximadamente un carácter de longitud cada doce.
  • Una palabra de la lista larga de la EFF son 12,925 bits, porque la lista tiene 7776 entradas, que son 6^5: cinco tiradas de dado.
  • Una palabra de la lista corta son 10,34 bits, de 1296 entradas, que son 6^4.

Un objetivo habitual son 128 bits, que es donde la fuerza bruta deja de ser una estrategia en lugar de ser meramente cara. Son 32 caracteres hex, 22 caracteres base64url o 10 palabras de la lista larga de la EFF.

Por qué no hay un único «tiempo hasta descifrarlo»

Un secreto no tiene tiempo de descifrado. Lo tiene la pareja formada por el secreto y aquello que lo guarda, y el guardián importa mucho más que el secreto. El mismo valor que tardaría más que la edad del universo en encontrarse a través de un formulario de acceso cae en una tarde si se guardó como un SHA-256 sin sal y la base de datos se filtró.

Por eso se muestran tres velocidades en vez de un número, y cada una lleva su nombre:

  • Diez intentos por segundo, contra un acceso que limita el ritmo. Es el techo realista para quien tenga que pasar por tu servicio.
  • Diez mil intentos por segundo, contra un hash de contraseñas filtrado y construido para ser lento: bcrypt con un coste moderno, o argon2. La lentitud es toda la razón de ser de esas funciones.
  • Un billón de intentos por segundo, contra un hash filtrado que nunca se pensó para contraseñas. SHA-256 y MD5 están diseñados para ser rápidos, y un equipo de GPU lo es muchísimo.

Las velocidades están redondeadas a potencias de diez a propósito. Cualquier cosa más precisa sugeriría una medición de un atacante concreto, cuando la información útil son los once órdenes de magnitud entre la primera fila y la última. Si un secreto va cómodo en las tres, la cuestión queda zanjada sin necesidad de las cifras exactas.

Cada cifra es la media, que es la mitad del espacio y no todo: una búsqueda encuentra la respuesta a mitad de camino por término medio. Y pasado el millón de años la respuesta se da como orden de magnitud, porque «cuatrocientos billones de años» no es una duración que nadie pueda comparar. El universo tiene unos 10^10 años, lo que sirve de referencia útil para las filas que llegan tan lejos.

Las frases de contraseña y de dónde sale realmente su fuerza

Una frase de contraseña es fuerte por una sola razón: varias palabras fueron elegidas al azar de una lista grande. No es fuerte por ser larga, ni por parecer lenguaje. Seis palabras al azar de una lista de 7776 son unos 77 bits; seis palabras que alguien haya pensado valen muchísimo menos, porque las personas no eligen de forma uniforme y un atacante sabe sobre las frases comunes lo mismo que tú.

Las dos listas de aquí vienen de la EFF y son las listas diceware publicadas, descargadas sin cambios. No son listas montadas aquí, y eso importa: una lista de palabras inventada por alguien tiene un tamaño desconocido, un solapamiento desconocido con otras listas y ninguna forma de comprobar la entropía que se le atribuye.

  • La lista larga tiene 7776 palabras, una por cada tirada de cinco dados, y da 12,925 bits por palabra.
  • La lista corta tiene 1296 palabras, una por cada tirada de cuatro dados, y da 10,34 bits por palabra. Sus palabras son más cortas —ninguna pasa de cinco letras— lo que facilita teclearlas a cambio de necesitar más palabras para la misma fuerza.

Una palabra repetida en una frase no es un defecto y aquí no se vuelve a extraer. Cada extracción es independiente, así que cualquier par concreto de palabras es exactamente igual de probable que cualquier otro; rechazar repeticiones encogería el espacio de frases posibles y las haría algo más débiles, no más fuertes.

Ambas listas de la EFF contienen un puñado de entradas con guion: t-shirt, yo-yo, drop-down, felt-tip. Si el separador es también un guion, una frase que contenga alguna de ellas no se puede volver a dividir en sus palabras sin ambigüedad. Es un problema de presentación y no de seguridad, y elegir un espacio o un punto como separador lo evita del todo.

Las opciones que cuestan entropía, y la que no

Excluir los caracteres parecidos cambia fuerza por legibilidad, y el cambio está a la vista. Quitar 0, O, I y l lleva el alfabeto alfanumérico de 62 caracteres a 58, que es, exactamente, el alfabeto base58 que usa Bitcoin, y por la misma razón. Cada carácter baja de 5,95 a 5,86 bits, así que un token necesita más o menos un carácter extra cada doce para seguir igual de fuerte. Suele merecer la pena para cualquier cosa que una persona vaya a leer en pantalla y teclear en otro sitio.

La opción solo se ofrece donde significa algo. Hex y base64url son codificaciones, no conjuntos de caracteres: sus alfabetos los fija una especificación, y un hex sin 0 ya no es hex; nada sería capaz de descodificarlo.

Poner mayúscula inicial en cada palabra de una frase no añade nada en absoluto, y la cifra de fuerza aquí deliberadamente no se mueve al activarlo. Es la misma transformación aplicada siempre, así que no crea ni una sola posibilidad nueva: un atacante que sepa que la frase lleva mayúsculas está exactamente donde empezó. La opción existe porque hay campos de contraseña que siguen exigiendo una mayúscula, no porque ayude.

Elegir la longitud

Para cualquier cosa que maneje una máquina —claves de API, tokens de sesión, secretos de webhook, contraseñas de base de datos— no hay razón para ser frugal. 32 caracteres hex o 22 base64url dan 128 bits, e ir más allá solo cuesta bytes en un fichero de configuración.

Para cualquier cosa que teclee una persona, la restricción es distinta y una frase de contraseña suele ser la mejor forma. Seis palabras de la lista larga son más fuertes que una contraseña aleatoria de doce caracteres y muchísimo más fáciles de acertar al primer intento, lo cual importa más de lo que parece: un secreto que la gente teclea mal es un secreto que la gente apunta.

Para un código numérico, la lectura honesta es que cuatro dígitos son 13 bits y se pueden agotar en segundos con cualquier cosa que no limite el ritmo. Un PIN solo es seguro por la política de bloqueo que lo rodea, nunca por su propia fuerza.

Preguntas frecuentes

¿Cuánto debe medir una clave de API?
Apunta a 128 bits de entropía o más, que es donde la fuerza bruta deja de ser una estrategia. Son 32 caracteres hex, 22 caracteres base64url, o 43 caracteres base64url si quieres 256 bits. Para un valor que solo maneja software, la opción más larga no cuesta nada.
¿Es esto más seguro que generar un secreto con Math.random?
Sí, y la diferencia no es de grado. Math.random es un generador pseudoaleatorio con un estado pequeño que los motores actuales permiten recuperar a partir de una tirada corta de salidas, tras lo cual se conocen todos los valores que producirá. Esta herramienta usa crypto.getRandomValues, el CSPRNG de la plataforma, que es la misma fuente de la que bebe openssl rand.
¿Por qué no mostráis un único «tiempo hasta descifrarlo»?
Porque no existe tal número. El mismo secreto es inalcanzable tras un acceso que limita el ritmo y cae rápido tras un hash rápido filtrado: once órdenes de magnitud de diferencia. Una sola cifra tiene que escoger un supuesto y luego esconderlo, y quien lee recuerda el número, no el supuesto. Tres velocidades con nombre ponen el supuesto donde se ve.
¿Son las frases de contraseña más débiles que una cadena aleatoria?
No: la fuerza depende únicamente de cuántas palabras se extraen de una lista de qué tamaño, y ambas cosas se muestran. Seis palabras de la lista larga de la EFF son unos 77 bits, más que una contraseña aleatoria de diez caracteres. Lo que debilita una frase es elegir tú las palabras, cosa que aquí no ocurre.
¿Debería excluir los caracteres parecidos?
Si una persona va a leer el secreto en pantalla y teclearlo en otro sitio, sí: el coste es pequeño y un token mal leído es un ticket de soporte. Si solo lo va a manejar software, no hay razón. Quitar 0, O, I y l lleva el alfabeto de 62 caracteres a 58, que es exactamente el alfabeto base58, y cuesta más o menos un carácter de longitud cada doce.
¿Poner mayúsculas en una frase la hace más fuerte?
No. Es el mismo cambio aplicado siempre, así que no añade ni una posibilidad nueva al espacio de frases. La cifra de entropía se queda quieta al activarlo, que es el comportamiento correcto. La opción está porque algunos campos de contraseña insisten en una mayúscula.
¿Se envía a un servidor algo de lo que genero?
No. La generación se ejecuta enteramente en tu navegador con el generador de aleatoriedad de la plataforma, nada se sube ni se registra, y funciona sin conexión de red. Los tokens no se guardan en ninguna parte: recargar la página produce otros nuevos y los anteriores desaparecen.