Passwortlecks und gehackte Anmeldedaten erkennen

Auf dieser Seite wird beschrieben, wie Sie die Funktion zur Erkennung von Passwortlecks von reCAPTCHA verwenden, um Passwortlecks und gehackte Anmeldedaten zu erkennen und so Kontoübernahmen (Account Takeovers, ATOs) und Credential Stuffing-Angriffe zu verhindern. Mit reCAPTCHA können Sie im Rahmen jeder Bewertung Nutzeranmeldedaten (Passwörter) regelmäßig prüfen, um sicherzustellen, dass diese nicht gehackt oder gehackt wurden. Für diese Prüfungen verwendet Google den Passwortcheck.

Hinweise

  1. Bereiten Sie Ihre Umgebung für reCAPTCHA vor.

  2. Richte reCAPTCHA ein.

  3. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.

    Für reCAPTCHA muss die Abrechnung für das Projekt verknüpft und aktiviert sein, um die Funktion zur Erkennung von Passwortlecks nutzen zu können. Sie können die Abrechnung aktivieren, indem Sie entweder eine Kreditkarte oder eine vorhandene Abrechnungs-ID eines Google Cloud-Projekts verwenden. Wenn Sie Unterstützung bei der Abrechnung benötigen, wenden Sie sich an den Cloud Billing-Support.

Auf gehackte und gehackte Anmeldedaten prüfen

Wenn Sie prüfen möchten, ob ein Satz von Anmeldedaten gehackt wurde, nutzen Sie die Erkennung von Passwortlecks, wenn Sie Prüfungen für Aktionen wie Anmeldungen, Passwortänderungen und Passwortzurücksetzungen erstellen.

Führen Sie die folgenden Schritte aus, um nach Passwortlecks und gehackten Anmeldedaten zu suchen:

  1. Anfrageparameter generieren:
  2. Bewertung erstellen, um Passwortlecks zu erkennen
  3. Verifizieren Sie gehackte Anmeldedaten aus einer Bewertung.
  4. Ergebnis interpretieren und Maßnahmen ergreifen:

Anfrageparameter generieren

  1. Berechnen Sie die erforderlichen Anfrageparameter mithilfe der kryptografischen Funktionen, die für das High-Privacy-Protokoll erforderlich sind. reCAPTCHA bietet Java- und TypeScript-Bibliotheken, die Sie beim Generieren dieser Felder unterstützen:

  2. Für Bestätigungen durch die Passwortprüfung müssen Sie ein PasswordCheckVerifier-Objekt erstellen.

    PasswordCheckVerifier verifier = new PasswordCheckVerifier();
    
  3. Rufen Sie PasswordCheckVerifier#createVerification an, um eine Bestätigung einzuleiten. 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();
    
  4. Erstellen Sie mithilfe der Bestätigungsparameter eine Bewertung.

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

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

Bewertung zur Erkennung von Passwortlecks erstellen

Verwenden Sie die Methode projects.assessments.create.

Bevor Sie die Anfragedaten verwenden, ersetzen Sie die folgenden Werte:

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

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

Gehackte Anmeldedaten aus einer Bewertung prüfen

Extrahieren Sie aus der Bewertungsantwort die Felder reEncryptedUserCredentials und encryptedLeakMatchPrefixes und übergeben Sie sie an das Verifizierungsobjekt, um festzustellen, ob die Anmeldedaten gehackt wurden.

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

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

Beurteilung interpretieren und Maßnahmen ergreifen

Die Antwort der Bewertung zeigt, ob die Anmeldedaten gehackt wurden, und liefert Ihnen Informationen, mit denen Sie geeignete Maßnahmen zum Schutz Ihrer Nutzer ergreifen können.

Die folgende Tabelle enthält die empfohlenen Maßnahmen, die Sie ergreifen können, wenn ein gehacktes Passwort erkannt wird:

Gehacktes Passwort erkannt Maßnahmen zum Schutz Ihrer Nutzer
Bei der Anmeldung
  • Lehnen Sie das Passwort ab, fordern Sie es auf, ein anderes Passwort auszuwählen, und lösen Sie nach Möglichkeit eine MFA-Abfrage aus.
  • Erinnern Sie den Nutzer daran, für jedes Konto ein eigenes Passwort zu verwenden.
  • Legen Sie auf Ihrer Website starke Passwörter fest.
  • Fordern Sie den Nutzer auf, die Multi-Faktor-Authentifizierung (MFA) zu aktivieren, wenn er sie nicht verwendet.
Bei der Kontoerstellung oder dem Zurücksetzen des Passworts
  • Nutzer auffordern, ihr Passwort zu ändern
  • Einen Multi-Faktor-Authentifizierungsvorgang (MFA) auslösen.

Wenn Sie auf Ihrer Website noch keinen MFA-Anbieter nutzen, können Sie die MFA-Funktion von reCAPTCHA nutzen.

Codebeispiel

Java

Richten Sie Standardanmeldedaten für Anwendungen ein, um sich bei reCAPTCHA zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.


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.PrivatePasswordLeakVerification;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import org.bouncycastle.util.encoders.Base64;

public class CreatePasswordLeakAssessment {

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

    // Username and password to be checked for credential breach.
    String username = "username";
    String password = "password";

    checkPasswordLeak(projectID, username, password);
  }

  /*
   * 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/check-passwords and
   * https://security.googleblog.com/2019/02/protect-your-accounts-from-data.html

   * Steps:
   * 1. Use the 'create' method to hash and Encrypt the hashed username and
   * password.
   * 2. Send the hash prefix (26-bit) and the encrypted credentials to create
   * the assessment.(Hash prefix is used to partition the database.)
   * 3. Password leak assessment returns a list of encrypted credential hashes to
   * be compared with the decryption of the returned re-encrypted credentials.
   * 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 26 bits 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 username, String password)
      throws ExecutionException, InterruptedException, IOException {

    // 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 = Base64.encode(verification.getLookupHashPrefix());
    byte[] encryptedUserCredentialsHash = Base64.encode(
        verification.getEncryptedUserCredentialsHash());

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

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

    // Verify if the encrypted credentials are present in the obtained match list.
    PasswordCheckResult result =
        passwordLeak
            .verify(
                verification,
                Base64.decode(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,
      byte[] lookupHashPrefix,
      byte[] encryptedUserCredentialsHash)
      throws IOException {
    try (RecaptchaEnterpriseServiceClient client = RecaptchaEnterpriseServiceClient.create()) {

      // 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()
                      // Set request for Password leak verification.
                      .setPrivatePasswordLeakVerification(passwordLeakVerification)
                      .build())
              .build();

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

      // 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();
    }
  }
}

Node.js (TypeScript)

Richten Sie Standardanmeldedaten für Anwendungen ein, um sich bei reCAPTCHA zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.


import {google} from '@google-cloud/recaptcha-enterprise/build/protos/protos';
import {RecaptchaEnterpriseServiceClient} from '@google-cloud/recaptcha-enterprise';
import {PasswordCheckVerification} from 'recaptcha-password-check-helpers';

// TODO(developer): Uncomment and set the following variables
// Google Cloud Project ID.
// const projectId: string = "PROJECT_ID"

// Username and password to be checked for credential breach.
// const username: string = "user123";
// const password: string = "1234@abcd";

// Create a client.
const client: RecaptchaEnterpriseServiceClient =
  new RecaptchaEnterpriseServiceClient();

/*
* 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/check-passwords and
* https://security.googleblog.com/2019/02/protect-your-accounts-from-data.html

* Steps:
* 1. Use the 'create' method to hash and Encrypt the hashed username and
* password.
* 2. Send the hash prefix (26-bit) and the encrypted credentials to create
* the assessment.(Hash prefix is used to partition the database.)
* 3. Password leak assessment returns a list of encrypted credential hashes to
* be compared with the decryption of the returned re-encrypted credentials.
* 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 Typescript.
* See, https://github.com/GoogleCloudPlatform/typescript-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 26 bits 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.
*/
async function checkPasswordLeak(
  projectId: string,
  username: string,
  password: string
) {
  // Instantiate the recaptcha-password-check-helpers library to perform the
  // cryptographic functions.
  // Create the request to obtain the hash prefix and encrypted credentials.
  const verification: PasswordCheckVerification =
    await PasswordCheckVerification.create(username, password);

  const lookupHashPrefix: string = Buffer.from(
    verification.getLookupHashPrefix()
  ).toString('base64');
  const encryptedUserCredentialsHash: string = Buffer.from(
    verification.getEncryptedUserCredentialsHash()
  ).toString('base64');
  console.log('Hashes created.');

  // Pass the credentials to the createPasswordLeakAssessment() to get back
  // the matching database entry for the hash prefix.
  const credentials: google.cloud.recaptchaenterprise.v1.IPrivatePasswordLeakVerification =
    await createPasswordLeakAssessment(
      projectId,
      lookupHashPrefix,
      encryptedUserCredentialsHash
    );

  // Convert to appropriate input format.
  const reencryptedUserCredentialsHash: Uint8Array = Buffer.from(
    credentials.reencryptedUserCredentialsHash!.toString(),
    'base64'
  );
  const encryptedLeakMatchPrefixes: Uint8Array[] =
    credentials.encryptedLeakMatchPrefixes!.map(prefix => {
      return Buffer.from(prefix.toString(), 'base64');
    });

  // Verify if the encrypted credentials are present in the obtained
  // match list to check if the credential is leaked.
  const isLeaked: boolean = verification
    .verify(reencryptedUserCredentialsHash, encryptedLeakMatchPrefixes)
    .areCredentialsLeaked();

  console.log(`Is Credential leaked: ${isLeaked}`);
}

// Create a reCAPTCHA Enterprise assessment.
// Returns: PrivatePasswordLeakVerification which contains
// reencryptedUserCredentialsHash and credential breach database whose prefix
// matches the lookupHashPrefix.
async function createPasswordLeakAssessment(
  projectId: string,
  lookupHashPrefix: string,
  encryptedUserCredentialsHash: string
): Promise<google.cloud.recaptchaenterprise.v1.IPrivatePasswordLeakVerification> {
  // Build the assessment request.
  const createAssessmentRequest: google.cloud.recaptchaenterprise.v1.ICreateAssessmentRequest =
    {
      parent: `projects/${projectId}`,
      assessment: {
        // Set the hashprefix and credentials hash.
        // Setting this will trigger the Password leak protection.
        privatePasswordLeakVerification: {
          lookupHashPrefix: lookupHashPrefix,
          encryptedUserCredentialsHash: encryptedUserCredentialsHash,
        },
      },
    };

  // Send the create assessment request.
  const [response] = await client.createAssessment(createAssessmentRequest);

  // Get the reCAPTCHA Enterprise score.
  console.log(`The reCAPTCHA score is: ${response.riskAnalysis?.score}`);
  // Get the assessment name (id). Use this to annotate the assessment.
  console.log(`Assessment name: ${response.name}`);

  if (!response?.privatePasswordLeakVerification) {
    throw `Error in obtaining response from Private Password Leak Verification ${response}`;
  }

  return response.privatePasswordLeakVerification;
}

checkPasswordLeak(projectId, username, password).catch(err => {
  console.error(err.message);
  process.exitCode = 1;
});

Nächste Schritte