Skip to main content

Endurecimiento de contraseñas con VOPRF para Django: una base de datos robada no se puede crackear offline.

Project description

quipu-oprf-django

Endurecimiento de contraseñas con VOPRF para Django. Una línea en PASSWORD_HASHERS y tu tabla de usuarios deja de ser crackeable offline.

Argon2 solo:   te roban la BD  ->  fuerza bruta offline, a la velocidad de su GPU.
Con OPRF:      te roban la BD  ->  no pueden derivar nada. Cada intento exige una
                                   petición a tu servidor: la ves, la limitas y la cortas.

El servidor nunca ve la contraseña (viaja cegada) y no puede mentir: cada respuesta trae una prueba DLEQ que el cliente verifica contra una clave pública que fijas tú.

Estado: beta. El servicio está pre-auditoría. Ver "Antes de producción".

Instalación

pip install quipu-oprf-django
# settings.py
PASSWORD_HASHERS = [
    "quipu_oprf_django.hashers.OprfArgon2PasswordHasher",   # preferido
    "django.contrib.auth.hashers.Argon2PasswordHasher",     # para migrar (ver abajo)
    "django.contrib.auth.hashers.PBKDF2PasswordHasher",
]

QUIPU_OPRF = {
    "BASE_URL":   os.environ["QUIPU_OPRF_URL"],      # https://oprf.xiliux.com
    "API_KEY":    os.environ["QUIPU_OPRF_API_KEY"],  # quipu_live_...
    "PUBLIC_KEY": os.environ["QUIPU_OPRF_PUBKEY"],   # 64 hex — ver "Fijar la clave"
    "TIMEOUT":    5.0,
}

Nada más. User.set_password() y authenticate() siguen funcionando igual.

Migrar usuarios existentes

No hace falta script. Deja Argon2PasswordHasher (o el que uses) después del nuestro en la lista: Django verifica cada hash antiguo con su hasher original y lo re-codifica con el preferido en el siguiente login correcto. Los usuarios migran solos según entran.

Fijar la clave pública

PUBLIC_KEY debe venir fuera de banda — del README de tu proveedor, de tu gestor de secretos, de donde sea menos del propio servidor.

Pedírsela a /v1/public-key anula la garantía: la prueba DLEQ demuestra que el servidor usó la clave correspondiente a la clave pública que tú fijaste. Si el servidor también elige contra qué se le verifica, un servidor comprometido puede responder lo que quiera. Por eso este paquete exige PUBLIC_KEY y no la descarga.

Instancia beta:

BASE_URL    https://oprf.xiliux.com
PUBLIC_KEY  88b623ccc00c9eac39f8e02a0f41851535dc2e196ed9836cad00f77644af214b

La clave cambió el 2026-07-17 (antes f84ef413…): la instancia migró a RFC 9497 y deriva la clave con DeriveKeyPair. Si fijaste la anterior, tu PUBLIC_KEY ya no valida y verás OprfRejected — que es exactamente lo que debe pasar cuando la clave fijada no cuadra. Actualízala.

Falla cerrado, a propósito

Si el servicio no responde, el login falla; no se degrada a Argon2 pelado.

No es rigidez: un hash sin endurecer no casaría con el guardado, así que degradar sería además de inseguro, incorrecto. Y verify() levanta en vez de devolver False, porque una caída no es una contraseña incorrecta — decir "clave errónea" durante un incidente de red manda al usuario a resetear su contraseña por nada.

Excepción Qué pasó Qué hacer
OprfUnavailable red, timeout, 5xx, o API key rechazada reintentar; mirar el servicio
OprfRejected la prueba DLEQ no valida contra tu clave fijada investigar: no lo produjo esa clave

OprfRejected nunca es un fallo transitorio. Significa servidor comprometido, suplantado, o PUBLIC_KEY mal configurada. No lo reintentes a ciegas.

Antes de producción

  • Cada login paga un viaje de red. Ajusta TIMEOUT y ten en cuenta la latencia hasta tu servidor OPRF.
  • El servicio es un punto único de fallo (R2 del modelo de amenaza): si cae, nadie entra. Planifica alta disponibilidad.
  • La semilla del servidor es crítica. Si se pierde, ningún usuario vuelve a entrar: los hashes guardados no se pueden reproducir. Respáldala.
  • Servicio en beta, pre-auditoría externa.

Licencia

Sin decidir, y hay que resolverlo antes de publicar.

El núcleo de Quipu es AGPL-3.0-or-later. Este plugin importa quipu, así que hoy la AGPL se propagaría a cualquier SaaS que lo instale — y ninguna empresa mete AGPL en sus PASSWORD_HASHERS. O sea: la licencia bloquearía la rampa de entrada al servicio de pago, que es exactamente lo que este paquete existe para abrir.

El patrón habitual de open-core es núcleo copyleft + SDK de cliente permisivo (Apache-2.0): MongoDB con SSPL y drivers Apache, Elastic, Redis. El titular único del copyright puede relicenciar el subconjunto del cliente VOPRF sin tocar el núcleo.

Pruebas

pip install -e ".[dev]" argon2-cffi
pytest

Las pruebas usan un doble de quipu que simula el contrato del VOPRF: aquí se verifica el cableado del plugin (clasificación de errores, fallo cerrado, migración), no la criptografía. Esa vive en Rust — src/voprf.rs, crates/quipu-oprf-server/tests/e2e.rs — y los 4 clientes de referencia se contrastan entre sí en scripts/oprf-e2e.sh.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

quipu_oprf_django-0.1.0.tar.gz (13.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

quipu_oprf_django-0.1.0-py3-none-any.whl (12.8 kB view details)

Uploaded Python 3

File details

Details for the file quipu_oprf_django-0.1.0.tar.gz.

File metadata

  • Download URL: quipu_oprf_django-0.1.0.tar.gz
  • Upload date:
  • Size: 13.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for quipu_oprf_django-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d419b2f6b4e24818c0c6ada102328de5e70510bfe3ac760f82eb1297168ba9d1
MD5 0e2af032e6f61afba5b5d0cab01fd4d3
BLAKE2b-256 c0fcc3cf92a05ddcc26a5cc05e83fedd1aa2e61b091dad5d33fb1dec6feeb5ab

See more details on using hashes here.

Provenance

The following attestation bundles were made for quipu_oprf_django-0.1.0.tar.gz:

Publisher: release.yml on isazajuancarlos/quipu

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quipu_oprf_django-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for quipu_oprf_django-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f018b9ffd4c6caae3d36051e77bedfe165ceac517f759498261ba184b5878476
MD5 8b9adba229054779e2dad4d54d06b46d
BLAKE2b-256 95ac97cd3a7645e90fc8d53c5ef234e1c23ae2210e5b595716bb6bfc8224c994

See more details on using hashes here.

Provenance

The following attestation bundles were made for quipu_oprf_django-0.1.0-py3-none-any.whl:

Publisher: release.yml on isazajuancarlos/quipu

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page