En esta página, se explica cómo verificar las contraseñas con nuestra base de datos de credenciales filtradas.
Esto se basa en el mismo sistema que Google usa en Revisión de contraseña.
Nuestra base de datos contiene más de 4 mil millones de credenciales filtradas y nuestra investigación ha demostrado que el 1.5% de los inicios de sesión en la web involucran credenciales vulneradas.
Antes de comenzar
Completa los pasos de la Guía de inicio rápido para obtener acceso a la API.
Solicitud a la API
Crea una evaluación mediante el método projects.assessments.create
.
Antes de usar cualquiera de los datos de solicitud siguientes, realiza estos reemplazos:
- project-id: Es el ID del proyecto de GCP.
- canonicalized_username: nombre de usuario convertido en canónico
- hashed_user_credentials: credenciales que tienen hash con Scrypt
Método HTTP y URL:
POST https://recaptchaenterprise.googleapis.com/v1beta1/projects/project-id/assessments
Cuerpo JSON de la solicitud:
{ "password_leak_verification": { "canonicalized_username": "canonicalized_username" "hashed_user_credentials": "hashed_user_credentials" } }
Para enviar tu solicitud, elige una de estas opciones:
curl
Guarda el cuerpo de la solicitud en un archivo llamado request.json
y ejecuta el siguiente comando:
curl -X POST \
-H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
https://recaptchaenterprise.googleapis.com/v1beta1/projects/project-id/assessments
PowerShell
Guarda el cuerpo de la solicitud en un archivo llamado request.json
y ejecuta el siguiente comando:
$cred = gcloud auth application-default print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }
Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://recaptchaenterprise.googleapis.com/v1beta1/projects/project-id/assessments" | Select-Object -Expand Content
Deberías recibir una respuesta JSON similar a la que se muestra a continuación:
{ "name": "projects/698047609967/assessments/fb22000000000000", "score": 0, "reasons": [], "passwordLeakVerification": { "hashedUserCredentials": "IDuS/soXlsLHmOm1A8zw+mChTI561MufdTaqL3k+zC4=", "credentialsLeaked": [true | false], "canonicalizedUsername": "test" } }
Canonicalización de nombre de usuario
Los nombres de usuario deben ser canonicalizados antes de llamar a la API. Simplemente escribe en minúscula el nombre de usuario, quita el componente de dominio y quita todos los puntos. Estos son algunos ejemplos:
- canonicalize(
foo.bar@COM
) =foobar
- canonicalize(
TEST@MAIL.COM
) =test
Un ejemplo de la lógica de canonicalización en Python:
#!/usr/bin/env python3
def canonicalize_username(username):
"""Canonicalize a username which must be a UTF-8 encoded string."""
if "@" in username:
username = username[:username.rfind("@")]
return username.lower().replace(".", "")
Procesa hashed_user_credentials
Se debe generar un hash en las credenciales de usuario antes de llamar a la API. Esto consiste en procesar el hash Scrypt del nombre de usuario canonicalizado y la contraseña con una sal fija. Debes procesar Scrypt(canonicalized_username + password + username_updated_salt)
en el que username_updated_salt = canonicalized_username + fixed_salt
y canonicalized_username
es la versión canonicalizada del nombre de usuario de la sección anterior.
Los parámetros de sal fijos y Scrypt se muestran en el siguiente ejemplo de Python:
#!/usr/bin/env python3
import base64
import hashlib
# Scrypt hash salt
USER_CREDENTIALS_HASH_SALT = [
48, 118, 42, 210, 63, 123, 161, 155, 248, 227, 66, 252, 161, 167, 141, 6,
230, 107, 228, 219, 184, 79, 129, 83, 197, 3, 200, 219, 189, 222, 165, 32
]
# Scrypt hash parameters and constants
SCRYPT_HASH_CPU_MEM_COST = 1 << 12
SCRYPT_HASH_BLOCK_SIZE = 8
SCRYPT_HASH_PARALLELIZATION = 1
SCRYPT_MAX_MEMORY = 1024 * 1024 * 32
SCRYPT_HASH_KEY_LENGTH = 32
def process_credentials(username, password):
"""Process user credentials to be used with the credentials check service."""
canonicalized_username = canonicalize_username(username)
# Compute the salt by appending the username to the fixed hash salt.
salt = bytes([ord(character) for character in list(canonicalized_username)] +
USER_CREDENTIALS_HASH_SALT)
# Compute the data to be hashed
data = bytes(canonicalized_username + password, encoding="utf8")
# Compute Scrypt hash using hashlib.
scrypt_hash = hashlib.scrypt(
password=data,
salt=salt,
n=SCRYPT_HASH_CPU_MEM_COST,
r=SCRYPT_HASH_BLOCK_SIZE,
p=SCRYPT_HASH_PARALLELIZATION,
maxmem=SCRYPT_MAX_MEMORY,
dklen=SCRYPT_HASH_KEY_LENGTH)
return canonicalized_username, base64.b64encode(scrypt_hash)
Aquí hay un ejemplo de hash codificado en base64 esperado, que puede usarse para verificar que tu implementación sea correcta.
- compute_scrypt_hash(
test@domain.com
,s0m3passw0rd!
) =1rzih02go6/dNcr1CQu9Ne+x4CC8xqSVuGaSWe+WhWk=