Una contraseña no se protege con una sola decisión
Un servicio no debería poder decir «guardamos las contraseñas con hash» y considerar terminado el diseño. Esa frase omite qué representación se procesa, cómo se separan cuentas que eligieron el mismo secreto, cuánto cuesta comprobar una conjetura, dónde se conserva una clave adicional, qué ocurre cuando cambia el algoritmo y qué camino permite reemplazar la contraseña. También omite dos adversarios distintos: quien prueba credenciales contra el servicio y quien roba el archivo de verificadores para probar conjeturas sin volver a interactuar con él.
Este capítulo construye el ciclo completo de una contraseña centralmente verificada: creación, transformación, almacenamiento, comprobación, migración, compromiso y recuperación. El objeto almacenado no es la contraseña ni un cifrado reversible de ella, sino un verificador derivado con una función de derivación de clave para contraseñas (KDF, por key derivation function), una sal única y parámetros registrados. Un secreto adicional del servidor —llamado habitualmente pepper— puede añadir una frontera, pero no sustituye la derivación costosa ni la separación de salts.
El caso conductor es Northstar, una plataforma que heredó tres generaciones de cuentas: SHA-256 sin salt, PBKDF2 con parámetros antiguos y Argon2id con parámetros actuales. El equipo debe migrarlas sin conocer las contraseñas, sostener el pico de autenticaciones, admitir Unicode sin producir equivalencias inesperadas y rediseñar un enlace de «olvidé mi contraseña» que hoy vale más que el verificador que pretende proteger.
El alcance termina en la contraseña y en su canal de recuperación. El capítulo 39 estudiará autenticación multifactor y resistencia al phishing. Aquí sólo se menciona otro autenticador cuando cambia la decisión de recuperación; no se presenta la contraseña como resistente al phishing ni se intenta convertir este capítulo en un catálogo de factores.
Dos ataques, dos presupuestos
En un ataque online, cada conjetura atraviesa la interfaz del verificador. El servicio puede medirla, introducir backoff y limitar intentos por cuenta, autenticador y contexto. NIST SP 800-63B-4 §3.2.2 fija cien fallos consecutivos como máximo, no como cuota instantánea: al alcanzar el límite, el autenticador se deshabilita y debe volver a vincularse antes de poder usarse. El backoff temporal reduce ritmo; no sustituye esa transición de estado ni autoriza desbloquear el mismo autenticador indefinidamente. NIST SP 800-63B-4, §§3.1.1.2 y 3.2.2
En un ataque offline, el adversario ya obtuvo salts, hashes, identificadores de algoritmo y parámetros. Puede probar candidatos localmente, distribuirlos y no recibir bloqueos por cuenta. El costo del defensor durante un inicio de sesión se convierte en el costo de cada conjetura del atacante, pero el atacante puede elegir hardware, paralelismo y candidatos más probables. Ningún rate limit del servicio alcanza esa copia robada. Por eso el almacenamiento debe hacer cara cada prueba y la política de creación debe impedir secretos que caen al comienzo de una estrategia de adivinación.
La distinción cambia cómo se interpreta la telemetría. Miles de fallos distribuidos pueden revelar un ataque online; que no existan esos eventos no permite concluir que los verificadores no se están atacando offline. A la inversa, endurecer el algoritmo de almacenamiento no impide credential stuffing con una contraseña válida obtenida en otro servicio. La arquitectura necesita controles diferentes y claims diferentes.
Desliza horizontalmente para leer el diagrama a tamaño completo.
El registro almacenado es una receta verificable, no un secreto reversible
Para una cuenta nueva, Northstar aplica una tubería determinista:
- recibe la contraseña completa por un canal protegido autenticado;
- valida límites y aplica exactamente la preparación Unicode declarada;
- genera una sal aleatoria propia del registro;
- ejecuta una función de derivación de contraseña con algoritmo y parámetros elegidos;
- si el diseño incluye pepper, aplica la operación con clave en la posición especificada y dentro de su frontera;
- almacena resultado, salt, algoritmo, versión, parámetros y versión de la clave adicional, pero nunca la contraseña.
El registro puede modelarse como:
account_id
algorithm = Argon2id
algorithm_version = 0x13
memory_kib = 65536
passes = 3
parallelism = 4
salt = random_per_record
verifier = derived_tag_or_keyed_transform
pepper_key_id = K-2026-04
input_profile = NFC-v1
La notación es un modelo editorial, no un formato de serialización de RFC 9106. La biblioteca puede usar una codificación distinta. Lo importante es que la verificación futura pueda reconstruir la misma función con los parámetros del registro y que una migración no dependa de valores globales que ya fueron reemplazados.
NIST exige almacenar las contraseñas centralmente verificadas en una forma resistente a ataques offline: salted y hashed con un esquema adecuado; también pide conservar una referencia al esquema y al factor de costo para permitir migración. La sal debe tener al menos 32 bits según ese perfil. RFC 9106 recomienda 16 bytes para Argon2 en aplicaciones de password hashing y que la sal sea única para cada contraseña; Northstar adopta esa recomendación más amplia. NIST SP 800-63B-4, §3.1.1.2 RFC 9106, §§3.1 y 4
No se cifra la contraseña para recuperarla después. Si el servicio puede descifrarla, una pérdida de la clave de cifrado recupera todos los secretos en claro y crea una capacidad operativa que la verificación no necesita. La excepción sería otra necesidad explícita que requiriese recuperar el valor —en cuyo caso ya no se está diseñando un verificador de contraseñas y el riesgo debe analizarse por separado—.
Desliza horizontalmente para leer el diagrama a tamaño completo.
Salt: unicidad pública, no una clave compartida
Una sal es un valor por registro que entra a la derivación. Puede almacenarse junto al hash; no depende de permanecer secreta. Su objetivo principal es que dos cuentas con la misma contraseña no produzcan el mismo verificador y que un atacante no pueda amortizar una tabla precalculada única sobre todos los registros.
La sal no vuelve fuerte una contraseña predecible. Con el registro robado, el atacante conoce la sal y puede derivar KDF(candidato, salt, parámetros) para cada candidato. Tampoco sirve una sal global reutilizada: aunque cambie respecto de otra base, dentro de la base reaparecen verificadores iguales para contraseñas iguales y se recupera parte de la amortización. La propiedad buscada es unicidad con una fuente aleatoria adecuada, no confidencialidad.
Un identificador de cuenta no es un reemplazo prudente de una sal aleatoria. Puede ser predecible, reutilizado entre entornos o transformarse durante una migración. Que un valor sea diferente en la base actual no garantiza las propiedades de generación, estabilidad y colisión que se esperan del campo salt.
Pepper: otra frontera, otra operación y otro ciclo de vida
Un pepper es un secreto del verificador usado además de la contraseña y la sal. A diferencia de la sal, no se guarda en el mismo conjunto de registros. NIST SP 800-63B-4 recomienda una iteración adicional de hash con clave o cifrado con una clave conocida sólo por el verificador, generada aleatoriamente y almacenada separada de los hashes, preferiblemente en un área protegida por hardware. NIST SP 800-63B-4, §3.1.1.2
La palabra pepper no define por sí sola la construcción. El diseño debe precisar si la clave entra en un parámetro secreto admitido por la KDF o si se aplica una función con clave al resultado, además de la codificación, longitud, identificador de clave y orden. Concatenar un secreto ambiguamente a la contraseña puede introducir colisiones de representación, incompatibilidades o una operación que la biblioteca nunca diseñó.
El beneficio está acotado. Si el adversario obtiene sólo la base de verificadores, una clave separada puede impedirle validar conjeturas. Si también compromete el servicio en ejecución, la cuenta de servicio o el módulo que usa la clave, esa barrera puede desaparecer. El pepper tampoco separa cuentas entre sí; esa función sigue perteneciendo a la sal.
La clave adicional introduce disponibilidad y rotación. Northstar guarda pepper_key_id, limita qué proceso puede solicitar la operación y conserva métricas del módulo sin registrar entradas. Perder la única clave puede impedir toda verificación. Rotarla no permite recalcular un verificador a partir del hash si la construcción requiere la contraseña original; puede exigir re-proteger una salida intermedia, migrar durante un login válido o forzar el reemplazo de contraseñas. La estrategia debe diseñarse antes del incidente, no después.
Una KDF de contraseña compra costo por conjetura
Una función hash rápida como SHA-256 está diseñada para procesar datos eficientemente. Esa propiedad es indeseable cuando el atacante repetirá la misma operación millones de veces. Una password hashing scheme o función de derivación para contraseñas introduce factores configurables de tiempo y, en diseños memory-hard, de memoria, con el fin de elevar el costo de cada prueba.
RFC 9106 describe Argon2 versión 1.3 y exige que las implementaciones de ese documento soporten Argon2id. Argon2id combina accesos independientes de los datos al inicio con accesos dependientes después; su elección busca equilibrar resistencia a ciertos canales laterales y costo de ataques con compromisos tiempo–memoria. El RFC ofrece dos configuraciones uniformes: una primera con 2 GiB y una pasada, y una segunda para entornos más restringidos con 64 MiB y tres pasadas, ambas con cuatro lanes, salt de 128 bits y tag de 256 bits. Son recomendaciones del CFRG en un RFC informativo, no parámetros que deban copiarse sin medir ni una declaración de aprobación FIPS. RFC 9106, §§1, 3.1, 4 y 7.4
Aquí, CFRG significa Crypto Forum Research Group y FIPS designa los estándares federales de procesamiento de información; ninguna de esas etiquetas convierte una recomendación de capacidad en un parámetro universal.
Los parámetros principales son:
m: memoria solicitada, expresada por RFC 9106 en kibibytes;t: número de pasadas;p: lanes o grado de paralelismo;- longitud de salt y de tag;
- variante y versión del algoritmo.
El objetivo no es maximizar una cifra aislada. Un servidor con 64 MiB por verificación y cien comprobaciones concurrentes puede demandar varios GiB sólo para esa función. Un límite agresivo puede convertirse en amplificación de denegación de servicio antes de autenticar a nadie. Uno demasiado bajo abarata el ataque offline. El presupuesto se obtiene midiendo en el hardware y runtime de producción: latencia de cola, memoria residente por operación, concurrencia, CPU, comportamiento del módulo de claves y objetivos de disponibilidad. Después se elige el mayor costo sostenible bajo carga adversa razonable, con límites de admisión y capacidad de degradar sin saltarse la verificación.
Para sistemas sujetos a normativa federal estadounidense, la frase «esquema aprobado» de NIST debe resolverse contra SP 800-132 y la política criptográfica vigente del sistema. SP 800-132 continúa publicado como documento final de 2010, pero NIST anunció en 2023 que planea revisarlo y considerar funciones memory-hard; esa intención no equivale todavía a una revisión final. RFC 9106 aporta una especificación y recomendaciones de Argon2id del CFRG, pero no convierte por sí solo a Argon2id en un algoritmo aprobado por NIST. Un documento de arquitectura debe registrar la versión y fecha del régimen aplicado en vez de fusionar ambos vocabularios.
Parámetros son parte del verificador y de la amenaza
Northstar no conserva sólo hash. Conserva una versión autocontenida de la receta. De ese modo, una cuenta antigua puede verificarse con sus parámetros originales y actualizarse después. Los parámetros por defecto de una biblioteca son insuficientes: pueden cambiar entre versiones, y un registro sin versión no permite distinguir qué se ejecutó.
La calibración necesita al menos cuatro ensayos:
- una verificación aislada, para medir el costo base;
- concurrencia de pico legítimo, para observar colas y memoria;
- presión adversa preautenticación, para probar rate limiting y límites de admisión;
- fallo de dependencias, especialmente indisponibilidad o latencia del servicio de pepper.
Los resultados deben incluir percentiles —por ejemplo, p50, p95 y p99—, no sólo un promedio. También deben separar una contraseña válida de una inválida y una cuenta existente de una inexistente: una optimización que evita la KDF únicamente para usuarios desconocidos puede crear un oráculo temporal de enumeración. Una defensa ilustrativa es realizar para ese camino una derivación equivalente con un registro sintético; su eficacia se mide extremo a extremo, porque base de datos, caché y red pueden seguir distinguiendo respuestas. No es una garantía normativa ni vuelve constante toda la solicitud.
Desliza horizontalmente para leer el diagrama a tamaño completo.
Verificación: misma representación, comparación acotada
JOSE significa JSON Object Signing and Encryption, y HSM significa módulo de seguridad hardware. Estas siglas describen contextos o componentes concretos; no amplían el alcance de la comparación.
La verificación reproduce la preparación declarada y la derivación indicada por el registro. El resultado calculado se compara con el verificador esperado. Cuando la biblioteca expone tags de longitud fija, la comparación debe evitar terminar en el primer byte distinto: un early return hace que el tiempo dependa de un prefijo secreto. RFC 7518 exige comparación constante para tags HMAC en su contexto JOSE; este capítulo transfiere ese principio a la comparación de verificadores de longitud fija, sin afirmar que RFC 7518 especifique password hashing. Se usa la primitiva de comparación constante de la biblioteca, con longitudes validadas antes y sin reimplementar un bucle «seguro» improvisado. RFC 7518, §3.2
Tiempo constante tiene aquí un alcance estrecho. Puede reducir la filtración del punto de diferencia en la comparación, pero no hace constante toda la solicitud. La selección de usuario, carga del registro, versión de KDF, coste de parámetros, llamada al HSM, rate limit y respuesta HTTP pueden variar. También puede haber microarquitectura, planificación y ruido. Por eso la propiedad se formula como «comparación del tag sin salida dependiente del prefijo», no como «login imposible de medir».
El flujo tampoco debe revelar si falló el usuario o la contraseña mediante mensajes, códigos o latencias innecesariamente distintos. Sin embargo, una respuesta uniforme no basta para demostrar ausencia de enumeración: se observan distribución temporal, tamaño, redirects, cookies, rate limits y telemetría. La instrumentación interna sí necesita motivos precisos, pero sin enviar el secreto ni convertir el log en un canal para el cliente.
Unicode: aceptar más caracteres exige una función estable
Una contraseña es una secuencia de entrada, pero interfaces distintas pueden producir secuencias Unicode diferentes que se ven iguales. La letra é puede representarse como un code point precompuesto o como e seguido de una marca combinante. Si el registro usa una representación y el login otra, el mismo gesto visible puede no verificar.
NIST SP 800-63B-4 recomienda aceptar Unicode, contar cada code point para el requisito de longitud y aplicar Normalization Form Canonical Composition (NFC) antes de convertir a bytes y derivar. También exige verificar la contraseña completa, sin truncarla. NIST SP 800-63B-4, §3.1.1.2 RFC 8265 define, para protocolos que adopten su perfil OpaqueString, preparación y enforcement ordenados: mapeo de ciertos espacios, ausencia de case mapping, NFC y comparación exacta octeto por octeto después de aplicar el perfil. RFC 8265, §§4.1–4.2.3
No se deben combinar ambas fuentes como si fueran una única política universal. Northstar declara input_profile = NFC-v1: valida que la entrada sea Unicode bien formado, aplica NFC tanto al registrar como al verificar, no cambia mayúsculas/minúsculas y codifica en UTF-8. Si un protocolo exige OpaqueString, adopta el perfil completo y lo versiona. Hacer sólo una parte —por ejemplo, reemplazar espacios como RFC 8265 pero olvidar sus demás reglas— crea una política nueva que debe evaluarse por sí misma.
La normalización canónica no es transliteración ni case folding. No debe eliminar acentos, confundir caracteres compatibles, recortar silenciosamente o transformar todas las mayúsculas. Cada tolerancia agrupa entradas distintas en una misma credencial y reduce el espacio efectivo. NIST permite concesiones limitadas para errores de escritura si se mantiene la longitud mínima y no se reduce significativamente la complejidad; una implementación que las use debe declararlas, aplicarlas de manera idéntica y probar qué equivalencias acepta. Northstar decide no usarlas.
Hay dos límites distintos. El límite de producto se expresa en caracteres o code points según la política; el límite de recursos también acota bytes normalizados para que una entrada patológica no consuma memoria desproporcionada. NIST recomienda permitir una longitud máxima de al menos 64 caracteres. Rechazar por encima de un máximo documentado es distinto de truncar: el truncamiento hace que dos entradas largas compartan el mismo prefijo verificado.
Cambiar el perfil Unicode es una migración de credenciales. Si la versión antigua derivó bytes diferentes, no se puede «normalizar el hash» existente. Se verifica con el perfil registrado y, después de una autenticación válida, se deriva un registro nuevo con el perfil vigente.
Desliza horizontalmente para leer el diagrama a tamaño completo.
Política de creación: longitud, blocklist y ayuda al usuario
NIST SP 800-63B-4 exige un mínimo de 15 caracteres cuando la contraseña es el único factor; permite un mínimo de ocho únicamente cuando nunca se acepta como autenticador independiente y siempre forma parte de la autenticación multifactor (MFA). MFA opcional, fallback password-only o recuperación por email no heredan automáticamente esa excepción. Prohíbe reglas adicionales de composición, cambios periódicos arbitrarios y preguntas de seguridad; exige cambio cuando existe evidencia de compromiso. También requiere permitir gestores de contraseñas y autofill, y recomienda permitir paste. NIST SP 800-63B-4, §§3.1.1.1–3.1.1.2
La blocklist se aplica al establecer o cambiar la contraseña. Debe comparar el secreto completo contra valores comunes, esperables, comprometidos y contextuales —por ejemplo, nombre del servicio o del usuario— y explicar al suscriptor por qué fue rechazado. NIST advierte que una lista excesivamente grande aporta poco beneficio incremental en el modelo online ya limitado y puede frustrar elecciones memorables. No exige buscar toda palabra de diccionario que aparezca como substring. NIST SP 800-63B-4, §3.1.1.2
Una blocklist no estima toda la entropía ni sustituye rate limiting. Su función es retirar candidatos que un atacante probaría pronto. Debe ejecutarse sobre la misma representación normalizada que se derivará; de lo contrario, variantes canónicamente equivalentes pueden producir decisiones distintas. Su versión y procedencia se registran para saber qué política evaluó una credencial, pero la contraseña rechazada no se registra.
La interfaz debe ayudar en vez de forzar patrones predecibles: permitir gestores, mostrar requisitos antes del envío, ofrecer revelar la entrada bajo control del usuario y emitir un motivo accionable cuando la blocklist rechaza. «Añade un símbolo y una mayúscula» suele transformar un valor débil de forma predecible; no es un sustituto de elegir otro secreto.
Rate limiting: reducir conjeturas sin crear un interruptor de cuentas
ASN significa sistema autónomo y NAT, traducción de direcciones de red. Se usan como señales de contexto, no como identidades.
El contador más importante se asocia al autenticador y a la cuenta, porque rotar direcciones IP no debe reiniciar el presupuesto. Señales por IP, dispositivo, red, ASN o reputación pueden complementar la decisión, pero compartir una dirección —NAT, proxy empresarial, carrier-grade NAT— impide tratarla como identidad. Un límite sólo por IP se evade distribuyendo intentos; uno sólo por cuenta puede usarse para causar bloqueos a víctimas.
Una política defendible combina:
- contador y ventana por cuenta/autenticador;
- demoras crecientes o backoff documentado;
- límites agregados por origen y por servicio;
- detección de password spraying y credential stuffing;
- ruta segura para reactivar o reemplazar el autenticador;
- notificación y telemetría sin revelar si una cuenta existe.
El efecto debe probarse. «Tenemos un firewall de aplicaciones web (WAF)» no demuestra que el endpoint alternativo, IPv6, la interfaz de programación de aplicaciones (API) móvil o la región secundaria compartan el mismo estado. Un control positivo verifica que una contraseña correcta dentro del presupuesto funciona; uno negativo supera el umbral con una cuenta sintética y confirma la decisión; uno de regresión distribuye intentos entre nodos y canales para comprobar que el presupuesto no se reinicia de forma imprevista.
Un bloqueo permanente tras pocos fallos convierte la autenticación en un mecanismo de denegación de servicio. Un contador que nunca expira y no tiene recuperación puede castigar errores legítimos. En cambio, un límite tan alto o reiniciado por cada nodo no cambia materialmente el ataque. La cifra y la respuesta se justifican con el riesgo, la fuerza de las contraseñas, el canal de recuperación y la arquitectura del servicio.
Migrar sin conservar para siempre el verificador débil
Northstar no puede convertir directamente SHA256(password) en Argon2id porque no conoce password. Aplicar Argon2id al hash antiguo produciría una construcción distinta, pero seguiría permitiendo al atacante que robó ambos campos atacar primero el SHA-256 rápido si éste se conserva o si la entrada efectiva del nuevo esquema es ese hash de bajo costo. La migración normal ocurre al recibir una contraseña válida.
El flujo es:
- leer algoritmo, parámetros y perfil del registro;
- verificar con el esquema antiguo dentro de un camino aislado y medido;
- si la contraseña es correcta, aplicar el perfil nuevo a la entrada original sólo si la compatibilidad está definida;
- generar nueva sal y derivar el nuevo verificador con parámetros vigentes;
- escribir de forma atómica el registro nuevo y retirar el débil;
- registrar la transición sin registrar secreto ni verificador completo.
Una cuenta que no vuelve a iniciar sesión permanece antigua. El sistema necesita una fecha límite y una decisión: deshabilitarla, forzar reset, exigir una nueva vinculación o aceptar temporalmente el riesgo. Mantener verificadores débiles indefinidamente para evitar fricción conserva el costo offline más barato precisamente en cuentas inactivas que pueden pasar desapercibidas.
El login válido también puede elevar parámetros de una cuenta ya Argon2id. Una función needs_rehash(record, policy) compara algoritmo, versión, m, t, p, longitud y versión de pepper/perfil; sólo después de verificar vuelve a derivar. La escritura debe ser segura ante concurrencia: dos logins simultáneos no deben restaurar una versión antigua ni perder el registro más nuevo.
No toda actualización espera al siguiente login. Una vulnerabilidad en el algoritmo, una exposición confirmada de la contraseña o una pérdida de la clave pepper puede exigir invalidación y reemplazo. El alcance depende de qué se comprometió: una base sin pepper, la base y el servicio de claves, o el endpoint que capturó entradas tienen consecuencias diferentes. El playbook conserva esa distinción.
Desliza horizontalmente para leer el diagrama a tamaño completo.
Reemplazo autenticado y account recovery no son autenticación equivalente
Un enlace de reset no es un login alternativo. Cambia el estado de los authenticators y puede permitir vincular una contraseña nueva, pero NIST separa ese ciclo de vida de la autenticación. Primero debe distinguirse el reemplazo autenticado —el suscriptor todavía puede autenticarse con otro authenticator válido y vincula uno nuevo— de account recovery, cuando perdió los authenticators necesarios. Ninguna ruta puede rebajar silenciosamente el nivel de assurance de autenticación (AAL), retirar un segundo factor o convertir una cuenta MFA en password-only. El análisis incluye iniciador, entrega, expiración, consumo, authenticator nuevo, sesiones afectadas y notificación independiente.
SP 800-63B-4 reconoce para recovery códigos guardados, códigos emitidos, contactos de recuperación y repetición de identity proofing. También exige notificación en todos los eventos de recuperación. Esos métodos recuperan la capacidad de vincular authenticators; el estándar advierte expresamente que recovery difiere de authentication. NIST SP 800-63B-4, §§4.1.2.1, 4.2 y 4.6
Para un reset por enlace, Northstar genera un valor aleatorio de uso único, conserva sólo un verificador del token, lo enlaza a cuenta, propósito y expiración, y lo invalida atómicamente al consumirse. El enlace se entrega por un canal previamente verificado. Solicitarlo produce una respuesta externa indistinguible exista o no la cuenta, pero sólo una cuenta válida origina el evento interno. El token no se coloca en logs, analytics ni cabeceras Referer; la página de consumo evita recursos de terceros que puedan recibir la URL.
Al completar el reset, el sistema:
- aplica la política de creación y crea una sal nueva;
- invalida todos los tokens de reset pendientes;
- decide y documenta si revoca sesiones existentes y credenciales derivadas;
- registra el cambio y envía una notificación independiente;
- ofrece un canal para reportar una acción no reconocida sin reutilizar el token consumido.
Un email no prueba por sí solo que quien lo recibe sea el suscriptor legítimo; prueba control del buzón en ese momento bajo los supuestos de ese canal. Preguntas como «nombre de la primera mascota» son secretos reutilizables, investigables y prohibidos por NIST como mecanismo de elección de contraseña. La recuperación de cuentas de mayor assurance requiere combinaciones más fuertes; sus reglas concretas dependen del AAL y del identity proofing, y no deben improvisarse a partir de un reset de bajo riesgo.
Desliza horizontalmente para leer el diagrama a tamaño completo.
Telemetría: observar el control sin coleccionar credenciales
La telemetría debe responder preguntas operativas y de seguridad sin transformar cada fallo en una filtración. Para cada intento puede registrar, con minimización y retención definidas:
- identificador pseudónimo o interno de cuenta, no la contraseña;
- resultado y motivo interno acotado;
- algoritmo y clase de parámetros, no el tag completo;
- versión de política, nodo, región y latencias por etapa;
- decisión de rate limit y contadores relevantes;
- señal de migración o
needs_rehash; - contexto de recuperación, emisión, consumo, expiración e invalidación;
- correlación con sesión y notificación sin copiar tokens.
Nunca se registran contraseñas, candidatos rechazados, tokens de reset, valores pepper ni dumps del request. Las salts no necesitan secreto criptográfico, pero tampoco suelen aportar valor en logs y facilitan correlación innecesaria. Los hashes pueden ser material para ataque offline: se tratan como credenciales sensibles, no como identificadores de depuración.
Las métricas agregadas separan volumen de fallos, cuentas objetivo, orígenes distribuidos, resets solicitados/consumidos, rehash pendientes, costo de KDF y errores del módulo de claves. Una caída brusca de latencia puede indicar que un camino omitió la KDF; un aumento puede ser ataque o cambio de capacidad. Ninguna señal adjudica sola la causa: se correlaciona con versión, despliegue, carga y controles sintéticos.
Caso trabajado: la migración de Northstar
El inventario inicial muestra:
Desliza horizontalmente para consultar todas las columnas.
Antes de migrar, el equipo prueba el pipeline de entrada. Descubre que el registro web aplicaba NFC, pero la API móvil derivaba bytes sin normalizar. No puede cambiar la API y asumir que todas las cuentas antiguas usaron NFC. Añade input_profile a cada cohorte, conserva la verificación exacta del perfil antiguo y migra a NFC-v1 sólo después de un éxito con el valor original. Las cuentas ambiguas pasan por reset; no se prueban múltiples transformaciones silenciosas en cada login, porque eso amplía equivalencias y multiplica el costo.
La calibración de Argon2id comienza en la segunda recomendación de RFC 9106 como candidato, no como resultado. Las pruebas de producción muestran que la memoria por operación es sostenible hasta cierta concurrencia, pero un ataque de usuarios inexistentes agotaría workers. El equipo añade admisión antes de reservar memoria, una derivación sintética equivalente para no crear una diferencia obvia de existencia y límites compartidos por región. Vuelve a medir p50, p95 y p99 con cuentas válidas, inválidas e inexistentes.
El pepper reside en un servicio de claves separado. El registro guarda su versión; el proceso de autenticación puede ejecutar la operación pero no exportar la clave. El equipo documenta que un proceso comprometido con capacidad de consultar ese servicio puede seguir verificando conjeturas, de modo que no afirma «la base es inútil sin el HSM» sin acotar la intrusión.
Por último, reemplaza el token de reset persistido en claro por un verificador de token, uso único, expiración y notificación independiente. Una prueba de carrera envía dos consumos simultáneos: exactamente uno debe vincular la contraseña nueva. Otra prueba solicita reset para una cuenta existente e inexistente y compara respuesta, tamaño, cookies y distribución temporal. Una tercera verifica que ningún log, traza o recurso de terceros recibe el token.
Qué puede afirmarse después de las pruebas
Northstar puede sostener: «Los registros de la cohorte C usan Argon2id versión 1.3 con salts aleatorias de 128 bits, receta versionada y una operación con clave separada; los parámetros fueron medidos bajo el perfil de carga L en el hardware H. Las cuentas A se invalidaron y las B pendientes vencen en T». Ese claim nombra población, algoritmo, frontera, fecha y límite.
No puede sostener «las contraseñas son seguras». El endpoint todavía puede sufrir phishing, malware, reutilización de credenciales o compromiso del servicio en ejecución. Tampoco puede afirmar que el pepper elimina el ataque offline si el atacante conserva acceso a la operación con clave. Y no puede inferir la fortaleza de una contraseña individual sólo porque pasó la longitud y la blocklist.
Síntesis
El sistema de contraseñas tiene dos economías. Contra ataques online, la interfaz limita intentos, detecta distribución y conserva una recuperación que no permita denegación fácil. Contra ataques offline, cada registro usa una sal única y una derivación deliberadamente costosa; un pepper separado puede añadir otra frontera si su operación, disponibilidad y rotación están diseñadas. Algoritmo, versión, parámetros y perfil de entrada forman parte del verificador.
Unicode exige aplicar la misma preparación antes de derivar y verificar, sin truncamiento ni equivalencias inventadas. La migración usa la contraseña sólo después de una verificación válida o fuerza reemplazo; no puede convertir mágicamente un hash rápido en conocimiento del secreto. El reemplazo autenticado y account recovery son eventos de lifecycle distintos de la autenticación y deben recibir rigor proporcional a su impacto. La telemetría observa decisiones, costos y ciclo de vida, pero nunca colecciona candidatos, verificadores o tokens como material de depuración.
Comprobación de comprensión
- Explica por qué rate limiting reduce un ataque online pero no cambia el presupuesto de quien robó la base de verificadores.
- Dos cuentas eligieron la misma contraseña. ¿Qué propiedad de una sal por registro evita que sus verificadores sean iguales y qué ataque no evita?
- Compara el compromiso de sólo la base, de la base más el servicio de pepper y del endpoint que recibe contraseñas.
- Diseña una calibración de Argon2id que incluya concurrencia, memoria, latencia y denegación de servicio; explica por qué copiar un valor del RFC no completa el trabajo.
- Una web aplicaba NFC y una app móvil no. Propón una migración que no pruebe varias equivalencias silenciosas para siempre.
- Explica el alcance exacto de una comparación constante del tag y menciona dos diferencias temporales que aún podrían enumerar cuentas.
- Diseña una migración de PBKDF2 antiguo a parámetros nuevos para cuentas activas e inactivas sin conservar indefinidamente el verificador débil.
- Clasifica primero un reset como reemplazo autenticado o account recovery y modela después su secreto, almacenamiento, expiración, consumo, revocación, notificación y controles de carrera.
- Reescribe «usamos Argon2id y por eso las contraseñas están seguras» como un claim comprobable con alcance y límites.
Fuentes principales
- National Institute of Standards and Technology, NIST SP 800-63B-4: Authentication and Authenticator Management, §§3.1.1, 3.2.2, 4.1–4.2 y 4.6, julio de 2025.
- A. Biryukov et al., RFC 9106: Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications, §§1, 3–4 y 7.4, septiembre de 2021.
- P. Saint-Andre y A. Melnikov, RFC 8265: Preparation, Enforcement, and Comparison of Internationalized Strings Representing Usernames and Passwords, §4, octubre de 2017.
- M. Jones, RFC 7518: JSON Web Algorithms, §3.2, mayo de 2015; se usa sólo para el principio acotado de comparación constante de tags, no como especificación de password hashing.
- National Institute of Standards and Technology, NIST SP 800-132: Recommendation for Password-Based Key Derivation, diciembre de 2010; citada para el alcance de esquemas aprobados que referencia SP 800-63B-4, no como recomendación de parámetros Argon2id.