Rilevare fughe di password e credenziali violate

reCAPTCHA Enterprise può rilevare fughe di password e credenziali violate per evitare violazioni degli account (ATO) e attacchi di credential stuffing. Con reCAPTCHA Enterprise, puoi eseguire controlli regolari delle credenziali utente (password) nell'ambito di qualsiasi valutazione per assicurarti che non siano state divulgate o violate. Per eseguire queste valutazioni, Google utilizza la funzionalità Controllo password.

Prima di iniziare

  1. Scegli il metodo migliore per la configurazione di reCAPTCHA Enterprise nel tuo ambiente e completa la configurazione.

  2. Il rilevamento di fuga delle password è accessibile dopo l'approvazione. Contatta il nostro team di vendita per inserire il tuo sito in questa funzionalità.

  3. Assicurati che la fatturazione sia attivata per il tuo progetto Cloud. Scopri come verificare se la fatturazione è abilitata su un progetto.

    Per utilizzare la funzionalità di rilevamento di fuga delle password, reCAPTCHA Enterprise richiede il collegamento e l'abilitazione della fatturazione nel progetto. Puoi abilitare la fatturazione utilizzando una carta di credito o un ID fatturazione di un progetto Google Cloud esistente. Se hai bisogno di aiuto con la fatturazione, contatta l'assistenza per la fatturazione Cloud.

Verifica la presenza di credenziali violate e/o divulgate

Per verificare se un insieme di credenziali è stato compromesso, interroga il database di controllo password durante le valutazioni per azioni, come accessi e modifiche o reimpostazioni della password.

Per usare il servizio di rilevamento di fuga delle password e determinare se si sia verificata una fuga o meno nella risposta, devi calcolare i parametri utilizzando le funzioni crittografiche richieste dal protocollo per l'alta privacy. A tale scopo, reCAPTCHA Enterprise fornisce una libreria Java: java-recaptcha-password-check-helpers.

Generare i parametri di richiesta

  1. Per creare verifiche verifiche password, crea un oggetto PasswordCheckVerifier.

    PasswordCheckVerifier verifier = new PasswordCheckVerifier();
    
  2. Per avviare una verifica, chiama il numero PasswordCheckVerifier#createVerification. Questo metodo utilizza il nome utente e la password per calcolare i parametri in modo da eseguire il controllo della password.

    PasswordCheckVerification verification = verifier.createVerification("username", "password").get();
    
  3. Crea una valutazione utilizzando i parametri di verifica.

    byte[] lookupHashPrefix = verification.getLookupHashPrefix();
    byte[] encryptedUserCredentialsHash = verification.getEncryptedUserCredentialsHash();
    

Gli array di byte lookupHashPrefix e encryptedUserCredentialsHash contengono i parametri necessari per avviare un controllo della password Assessment.

Richiesta API

Utilizza il metodo projects.assessments.create.

Prima di utilizzare uno qualsiasi dei dati della richiesta, effettua le seguenti sostituzioni:

  • PROJECT_ID: il tuo ID progetto Google Cloud
  • LOOKUP_HASH_PREFIX: prefisso del prefisso hash di crittografia del nome utente
  • ENCRYPTED_USER_CREDENTIALS_HASH: hash di credenziali SHA-256 utente criptato

Metodo HTTP e URL:

POST https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments

Corpo JSON richiesta:

{
  "private_password_leak_verification": {
    "lookup_hash_prefix": "LOOKUP_HASH_PREFIX"
    "encrypted_user_credentials_hash": "ENCRYPTED_USER_CREDENTIALS_HASH"
  }
}

Per inviare la richiesta, scegli una delle seguenti opzioni:

Curling

Salva il corpo della richiesta in un file denominato request.json ed esegui il seguente 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/v1/projects/PROJECT_ID/assessments"

PowerShell

Salva il corpo della richiesta in un file denominato request.json ed esegui il seguente 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/v1/projects/PROJECT_ID/assessments" | Select-Object -Expand Content

Dovresti ricevere una risposta JSON simile alla seguente:

{
  "name": "projects/698047609967/assessments/fb22000000000000",
  "score": 0,
  "reasons": [],
  "privatePasswordLeakVerification": {
    "lookupHashPrefix": "zoxZwA==",
    "encryptedUserCredentialsHash": "AyRihRcKaGLj/FA/r2uqQY/fzfTaDb/nEcIUMeD3Tygp",
    "reencryptedUserCredentialsHash": "Aw65yEbLM39ww1ridDEfx5VhkWo11tzn/R1B88Qqwr/+"
    "encryptedLeakMatchPrefixes": [
      "n/n5fvPD6rmQPFyb4xk=", "IVQqzXsbZenaibID6OI=", ..., "INeMMndrfnlf6osCVvs=",
      "MkIpxt2x4mtyBnRODu0=", "AqUyAUWzi+v7Kx03e6o="]
  }
}

Verificare una fuga delle password

Dalla risposta di CreateAssessment, estrai i campi reEncryptedUserCredentials e encryptedLeakMatchPrefixes e passali all'oggetto dello strumento di verifica per determinare se le credenziali sono state divulgate o meno.

PasswordCheckResult result = verifier.verify(verification,
  result.getReEncryptedUserCredentials(),
  result.getEncryptedLeakMatchPrefixes()
).get();

System.out.println("Credentials leaked: " + result.areCredentialsLeaked());

Esempio di codice

Java


import com.google.cloud.recaptcha.passwordcheck.PasswordCheckResult;
import com.google.cloud.recaptcha.passwordcheck.PasswordCheckVerification;
import com.google.cloud.recaptcha.passwordcheck.PasswordCheckVerifier;
import com.google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseServiceClient;
import com.google.protobuf.ByteString;
import com.google.recaptchaenterprise.v1.Assessment;
import com.google.recaptchaenterprise.v1.CreateAssessmentRequest;
import com.google.recaptchaenterprise.v1.Event;
import com.google.recaptchaenterprise.v1.PrivatePasswordLeakVerification;
import com.google.recaptchaenterprise.v1.TokenProperties;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

public class CreatePasswordLeakAssessment {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException {
    // TODO(developer): Replace these variables before running the sample.
    // GCloud Project ID.
    String projectID = "project-id";

    // Site key obtained by registering a domain/app to use recaptcha Enterprise.
    String recaptchaSiteKey = "recaptcha-site-key";

    // The token obtained from the client on passing the recaptchaSiteKey.
    // To get the token, integrate the recaptchaSiteKey with frontend. See,
    // https://cloud.google.com/recaptcha-enterprise/docs/instrument-web-pages#frontend_integration_score
    String token = "recaptcha-token";

    // Action name corresponding to the token.
    String recaptchaAction = "recaptcha-action";

    checkPasswordLeak(projectID, recaptchaSiteKey, token, recaptchaAction);
  }

  /*
  * Detect password leaks and breached credentials to prevent account takeovers (ATOs)
  * and credential stuffing attacks.
  * For more information, see: https://cloud.google.com/recaptcha-enterprise/docs/getting-started
  * and https://security.googleblog.com/2019/02/protect-your-accounts-from-data.html

  * Steps:
  * 1. Use the 'createVerification' method to hash and Encrypt the hashed username and password.
  * 2. Send the hash prefix (2-byte) and the encrypted credentials to create the assessment.
  * (Hash prefix is used to partition the database.)
  * 3. Password leak assessment returns a database whose prefix matches the sent hash prefix.
  * Create Assessment also sends back re-encrypted credentials.
  * 4. The re-encrypted credential is then locally verified to see if there is a
  * match in the database.
  *
  * To perform hashing, encryption and verification (steps 1, 2 and 4),
  * reCAPTCHA Enterprise provides a helper library in Java.
  * See, https://github.com/GoogleCloudPlatform/java-recaptcha-password-check-helpers

  * If you want to extend this behavior to your own implementation/ languages,
  * make sure to perform the following steps:
  * 1. Hash the credentials (First 2 bytes of the result is the 'lookupHashPrefix')
  * 2. Encrypt the hash (result = 'encryptedUserCredentialsHash')
  * 3. Get back the PasswordLeak information from reCAPTCHA Enterprise Create Assessment.
  * 4. Decrypt the obtained 'credentials.getReencryptedUserCredentialsHash()'
  * with the same key you used for encryption.
  * 5. Check if the decrypted credentials are present in 'credentials.getEncryptedLeakMatchPrefixesList()'.
  * 6. If there is a match, that indicates a credential breach.
  */
  public static void checkPasswordLeak(
      String projectID, String recaptchaSiteKey, String token, String recaptchaAction)
      throws ExecutionException, InterruptedException, IOException {
    // Set the username and password to be checked.
    String username = "username";
    String password = "password123";

    // Instantiate the java-password-leak-helper library to perform the cryptographic functions.
    PasswordCheckVerifier passwordLeak = new PasswordCheckVerifier();

    // Create the request to obtain the hash prefix and encrypted credentials.
    PasswordCheckVerification verification =
        passwordLeak.createVerification(username, password).get();

    byte[] lookupHashPrefix = verification.getLookupHashPrefix();
    byte[] encryptedUserCredentialsHash = verification.getEncryptedLookupHash();

    // Pass the credentials to the createPasswordLeakAssessment() to get back
    // the matching database entry for the hash prefix.
    PrivatePasswordLeakVerification credentials =
        createPasswordLeakAssessment(
            projectID,
            recaptchaSiteKey,
            token,
            recaptchaAction,
            lookupHashPrefix,
            encryptedUserCredentialsHash);

    // Convert to appropriate input format.
    List<byte[]> leakMatchPrefixes =
        credentials.getEncryptedLeakMatchPrefixesList().stream()
            .map(ByteString::toByteArray)
            .collect(Collectors.toList());

    // Verify if the encrypted credentials are present in the obtained match list.
    PasswordCheckResult result =
        passwordLeak
            .verify(
                verification,
                credentials.getReencryptedUserCredentialsHash().toByteArray(),
                leakMatchPrefixes)
            .get();

    // Check if the credential is leaked.
    boolean isLeaked = result.areCredentialsLeaked();
    System.out.printf("Is Credential leaked: %s", isLeaked);
  }

  // Create a reCAPTCHA Enterprise assessment.
  // Returns:  PrivatePasswordLeakVerification which contains
  // reencryptedUserCredentialsHash and credential breach database
  // whose prefix matches the lookupHashPrefix.
  private static PrivatePasswordLeakVerification createPasswordLeakAssessment(
      String projectID,
      String recaptchaSiteKey,
      String token,
      String recaptchaAction,
      byte[] lookupHashPrefix,
      byte[] encryptedUserCredentialsHash)
      throws IOException {
    try (RecaptchaEnterpriseServiceClient client = RecaptchaEnterpriseServiceClient.create()) {

      // Set the properties of the event to be tracked.
      Event event = Event.newBuilder().setSiteKey(recaptchaSiteKey).setToken(token).build();

      // Set the hashprefix and credentials hash.
      // Setting this will trigger the Password leak protection.
      PrivatePasswordLeakVerification passwordLeakVerification =
          PrivatePasswordLeakVerification.newBuilder()
              .setLookupHashPrefix(ByteString.copyFrom(lookupHashPrefix))
              .setEncryptedUserCredentialsHash(ByteString.copyFrom(encryptedUserCredentialsHash))
              .build();

      // Build the assessment request.
      CreateAssessmentRequest createAssessmentRequest =
          CreateAssessmentRequest.newBuilder()
              .setParent(String.format("projects/%s", projectID))
              .setAssessment(
                  Assessment.newBuilder()
                      .setEvent(event)
                      // Set request for Password leak verification.
                      .setPrivatePasswordLeakVerification(passwordLeakVerification)
                      .build())
              .build();

      // Send the create assessment request.
      Assessment response = client.createAssessment(createAssessmentRequest);

      // Check validity and integrity of the response.
      if (!checkTokenIntegrity(response.getTokenProperties(), recaptchaAction)) {
        return passwordLeakVerification;
      }

      // Get the reCAPTCHA Enterprise score.
      float recaptchaScore = response.getRiskAnalysis().getScore();
      System.out.println("The reCAPTCHA score is: " + recaptchaScore);

      // Get the assessment name (id). Use this to annotate the assessment.
      String assessmentName = response.getName();
      System.out.println(
          "Assessment name: " + assessmentName.substring(assessmentName.lastIndexOf("/") + 1));

      return response.getPrivatePasswordLeakVerification();
    }
  }

  // Check for token validity and action integrity.
  private static boolean checkTokenIntegrity(
      TokenProperties tokenProperties, String recaptchaAction) {
    // Check if the token is valid.
    if (!tokenProperties.getValid()) {
      System.out.println(
          "The Password check call failed because the token was: "
              + tokenProperties.getInvalidReason().name());
      return false;
    }

    // Check if the expected action was executed.
    if (!tokenProperties.getAction().equals(recaptchaAction)) {
      System.out.printf(
          "The action attribute in the reCAPTCHA tag '%s' does not match "
              + "the action '%s' you are expecting to score",
          tokenProperties.getAction(), recaptchaAction);
      return false;
    }
    return true;
  }
}