Artículo invitado de Iliya Garakh, Process Improvement & Agile Methodologies.
Primera entrega de una serie de cuatro sobre cómo comprobar contraseñas filtradas sin revelarlas al servicio que responde. En esta entrega planteamos el problema, fijamos el modelo de amenaza y vemos por qué los enfoques basados solo en el hash —incluso con sal o con bcrypt— no resuelven la cuestión.
Una pregunta práctica a la que tarde o temprano se enfrenta todo gestor de contraseñas, plataforma de inicio de sesión único y sistema de autenticación empresarial: ¿cómo comprobar contraseñas filtradas sin revelarlas al operador del servicio de consulta? Servicios como Have I Been Pwned (HIBP) han popularizado el problema y propuesto su propia respuesta —el modelo k-anonymity— pero la pregunta de fondo sigue abierta: ¿cuánta información sobre la contraseña aprende inevitablemente quien responde la consulta?
La respuesta ingenua —«calcular el hash y preguntar»— filtra el secreto. La respuesta habitual —«enviar un prefijo del hash», el modelo k-anonymity de HIBP— filtra menos, pero más de lo deseable. Las respuestas criptográficamente puras (OPRF, PSI) funcionan, pero exigen operaciones sobre curvas elípticas en cada consulta. Existe una capa intermedia en el espacio de diseño: construir el corpus de filtraciones como un filtro de Bloom y dejar que el cliente consulte celdas individuales del filtro mientras oculta las que realmente le interesan mediante ruido de ofuscación determinista.
Esta serie recorre ese esquema de principio a fin: qué hace bien, qué hace mal y en qué contextos debería o no desplegarse. En esta primera entrega situamos el problema y descartamos las soluciones obvias.
1. El problema
Los corpus de filtraciones —el acúmulo de credenciales expuestas por brechas de seguridad durante las últimas dos décadas— son ya infraestructura normalizada. Have I Been Pwned registra por sí solo más de trece mil millones de cuentas comprometidas, y la mayoría de las organizaciones consideran alguna forma de cribado de credenciales filtradas un control de base: en el registro, en el cambio de contraseña, en el inicio de sesión o como auditoría periódica de secretos almacenados. Es la línea de defensa más directa contra credential stuffing.
El control es sencillo en principio: el usuario proporciona una contraseña y se quiere responder a la pregunta:
«¿Figura esta contraseña —o su hash, o algún derivado— en un corpus de filtraciones conocido públicamente?»
El control es difícil en la práctica porque el propio proceso de verificación constituye una frontera de privacidad. Quien realice la consulta aprende algo sobre la contraseña comprobada —en el límite, la propia contraseña—. El problema que se quiere resolver no es simplemente «encontrar una consulta rápida»; es diseñar un protocolo en el que:
- el servidor pueda responder correctamente sí / no / probablemente sí para cualquier contraseña,
- el servidor aprenda la menor información posible sobre la contraseña consultada, y
- el protocolo funcione dentro de los presupuestos de latencia, ancho de banda y almacenamiento de los sistemas reales.
2. Modelo de amenaza
Se asume:
- Servidor honesto pero curioso. El servidor ejecuta el protocolo correctamente —no devuelve respuestas maliciosas— pero registra todas las consultas y puede analizarlas fuera de línea para inferir información sobre las contraseñas consultadas.
- Adversario con acceso al corpus público de filtraciones. El corpus es, por su propia naturaleza, conocido por cualquiera que desee descargarlo.
- Adversario persistente. Las consultas se correlacionan en el tiempo; el servidor puede almacenar todas las peticiones de un cliente y buscar patrones entre ellas, incluyendo consultas sobre la misma contraseña emitidas con meses de diferencia.
- Transporte cifrado. Comunicación cliente–servidor sobre TLS. No se considera la interceptación a nivel de enlace.
- Cliente capaz de custodiar un secreto a largo plazo. Requisito esencial del esquema; volveremos sobre sus implicaciones más adelante en la serie.
Se excluyen explícitamente: un servidor completamente malicioso, ataques por canal lateral contra el cliente (temporización, caché, electromagnéticos) y el compromiso del dispositivo cliente, incluida la extracción de su secreto. Estas exclusiones son relevantes: el esquema no ofrece defensa frente a un servidor que mienta, y un único compromiso del cliente anula las garantías de privacidad para todas sus consultas pasadas.
3. Por qué el hash por sí solo no es suficiente
Envío directo del hash. El cliente envía H (pw) y el servidor comprueba la pertenencia al conjunto. Frente a un servidor con el corpus de filtraciones, esto es equivalente a enviar la contraseña: las tablas arcoíris y los ataques de diccionario recuperan la contraseña en claro desde SHA-1, SHA-256 o bcrypt con factor de coste bajo. El servidor no necesita romper el hash; le basta con buscarlo en una tabla precalculada.
Sal (salt). Una sal solo es útil si el adversario la desconoce. En la comprobación de filtraciones, cliente y servidor deben acordar cómo derivar la clave de búsqueda, por lo que cualquier sal es estructuralmente pública. Las sales por usuario impiden la correlación entre usuarios, pero no la identificación mediante una única consulta.
Hashes iterados y resistentes en memoria. Argon2, scrypt y bcrypt elevan el coste de probar cada candidato, pero no cambian la dinámica fundamental: el servidor aprende una función determinista de pw y puede realizar búsquedas en diccionarios. Reducen la tasa del ataque, no su resultado final.
La conclusión es que el objetivo de privacidad es incompatible con que el servidor vea cualquier función determinista única de la contraseña sin que esa función esté parametrizada con un secreto del servidor inobservable por el cliente. Esta última idea es exactamente la de las OPRF (oblivious pseudorandom functions), que usan Google Password Checkup y Apple iCloud Keychain y que abordaremos más adelante. El esquema que nos ocupa toma otra vía: descomponer la operación de búsqueda en muchas subconsultas pequeñas e individualmente insignificantes, y ocultar cuáles son las reales.
En la segunda entrega repasaremos las propiedades de los filtros de Bloom que hacen viable esta idea y construiremos el protocolo de índices ofuscados paso a paso, explicando por qué el ruido tiene que ser determinista y qué ocurre si no lo es.
Sobre el autor
Iliya Garakh tiene un máster en Matemáticas Aplicadas y Criptografía.

Speak Your Mind