Esta página se ha traducido con Cloud Translation API.
Switch to English

Verificación de contraseñas

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=