Passwortlecks und gehackte Anmeldedaten erkennen

reCAPTCHA Enterprise kann Passwortlecks und gehackte Anmeldedaten erkennen, um Kontoübernahmen (ATOs) und Credential Stuffing-Angriffe zu verhindern. Mit reCAPTCHA Enterprise können Sie im Rahmen jeder Bewertung regelmäßig Audits von Nutzeranmeldedaten (Passwörtern) ausführen, um sicherzustellen, dass sie nicht manipuliert oder gehackt wurden. Zur Durchführung dieser Bewertungen verwendet Google die Passwortcheck-Funktion.

Hinweis

  1. Wählen Sie die beste Methode zum Einrichten von reCAPTCHA Enterprise in Ihrer Umgebung aus und schließen Sie die Einrichtung ab.

  2. Die Erkennung von Datenlecks ist nach der Genehmigung verfügbar. Wenden Sie sich an unser Vertriebsteam, um Ihre Website auf dieses Feature umzustellen.

  3. Die Abrechnung für das Cloud-Projekt muss aktiviert sein. So prüfen Sie, ob die Abrechnung für ein Projekt aktiviert ist.

    reCAPTCHA Enterprise erfordert die Verknüpfung und Aktivierung der Abrechnung für das Projekt, um die Funktion zur Erkennung von Passwortlecks verwenden zu können. Sie können die Abrechnung entweder mit einer Kreditkarte oder mit einer bestehenden Abrechnungs-ID für das Google Cloud-Projekt aktivieren. Wenn Sie Hilfe bei der Abrechnung benötigen, wenden Sie sich an den Cloud Billing-Support.

Nach gehackten und/oder gehackten Anmeldedaten suchen

Wenn Sie prüfen möchten, ob ein Satz Anmeldedaten manipuliert wurde, fragen Sie die Passwortcheck-Datenbank während der Bewertung von Aktionen ab, darunter Anmeldungen und Passwortänderungen oder -zurücksetzungen.

Wenn du den Dienst zur Datenleck-Erkennung verwenden und feststellen möchtest, ob es ein Leck gab, musst du die Parameter mit den kryptografischen Funktionen berechnen, die für das Protokoll mit hohem Datenschutz erforderlich sind. Dazu stellt reCAPTCHA Enterprise eine Java-Bibliothek zur Verfügung: java-recaptcha-password-check-helpers.

Anfrageparameter generieren

  1. Erstelle zur Überprüfung von Passwortprüfungen ein PasswordCheckVerifier-Objekt.

    PasswordCheckVerifier verifier = new PasswordCheckVerifier();
    
  2. Rufen Sie PasswordCheckVerifier#createVerification auf, um die Bestätigung zu starten. Bei dieser Methode werden der Nutzername und das Passwort verwendet, um die Parameter für die Passwortprüfung zu berechnen.

    PasswordCheckVerification verification = verifier.createVerification("username", "password").get();
    
  3. Erstellen Sie eine Bewertung mithilfe der Bestätigungsparameter.

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

Die Bytearrays lookupHashPrefix und encryptedUserCredentialsHash enthalten die Parameter, die zum Initiieren einer Passwortprüfung Assessment erforderlich sind.

API-Anfrage

Verwenden Sie die Methode projects.assessments.create.

Bevor Sie eine der Anfragedaten verwenden, nehmen Sie folgende Ersetzungen vor:

  • PROJECT_ID: Ihre Google Cloud-Projekt-ID
  • LOOKUP_HASH_PREFIX: Präfix des Scrypt-Hash-Präfixes des Nutzernamens
  • ENCRYPTED_USER_CREDENTIALS_HASH: SHA-256-Hash der verschlüsselten Nutzeranmeldedaten

HTTP-Methode und URL:

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

JSON-Text der Anfrage:

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

Wenn Sie die Anfrage senden möchten, wählen Sie eine der folgenden Optionen aus:

curl

Speichern Sie den Anfragetext in einer Datei mit dem Namen request.json und führen Sie den folgenden Befehl aus:

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

Speichern Sie den Anfragetext in einer Datei mit dem Namen request.json und führen Sie den folgenden Befehl aus:

$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

Sie sollten in etwa folgende JSON-Antwort erhalten:

{
  "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="]
  }
}

Passwortleck bestätigen

Extrahieren Sie aus der CreateAssessment-Antwort die Felder reEncryptedUserCredentials und encryptedLeakMatchPrefixes und übergeben Sie sie an das Verifikationsobjekt, um festzustellen, ob die Anmeldedaten gehackt wurden.

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

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

Codebeispiel

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;
  }
}