Detete fugas de palavras-passe e credenciais violadas

Esta página descreve como usar a funcionalidade de defesa de palavras-passe do reCAPTCHA para detetar fugas de palavras-passe e credenciais violadas para evitar a apropriação de contas (ATOs) e ataques de preenchimento de credenciais. Com o reCAPTCHA, pode realizar auditorias regulares das credenciais dos utilizadores (palavras-passe) como parte de qualquer avaliação para garantir que não foram divulgadas nem violadas. Para realizar estas avaliações, a Google usa a funcionalidade Verificação de Palavra-passe.

Antes de começar

  1. Prepare o seu ambiente para o reCAPTCHA.

  2. Configure o reCAPTCHA.

  3. Verify that billing is enabled for your Google Cloud project.

    O reCAPTCHA requer que a faturação esteja associada e ativada no projeto para usar a funcionalidade de defesa de palavras-passe. Pode ativar a faturação através de um cartão de crédito ou de um ID de faturação do projeto existente Google Cloud . Se precisar de assistência com a faturação, contacte o apoio técnico do Cloud Billing.

Verifique se existem credenciais violadas e roubadas

Pode verificar se um conjunto de credenciais foi comprometido através de funções criptográficas ou do contentor Docker.

O contentor Docker é um cliente de código aberto que implementa a computação multipartidária segura necessária para preservar a privacidade do utilizador final e procurar fugas de palavras-passe de forma segura. Para mais informações, consulte o repositório do GitHub. O contentor Docker abstrai a complexidade da implementação dos algoritmos criptográficos e simplifica o processo de instalação. Também lhe permite alojar a app de contentor na sua infraestrutura.

Função criptográfica

Para verificar se um conjunto de credenciais foi comprometido, use a defesa por palavra-passe quando criar avaliações para ações como inícios de sessão, alterações de palavras-passe e reposições de palavras-passe.

Para verificar se existem fugas de palavras-passe e credenciais violadas, conclua os seguintes passos:

  1. Gerar parâmetros de pedido.
  2. Crie uma avaliação para detetar fugas de palavras-passe.
  3. Valide credenciais roubadas de uma avaliação.
  4. Interprete o veredito e tome medidas.

Gere parâmetros de pedido

  1. Calcule os parâmetros de pedido necessários através das funções criptográficas exigidas pelo protocolo de elevada privacidade. O reCAPTCHA fornece bibliotecas Java e TypeScript para ajudar na geração destes campos:

  2. Para criar validações de verificação das palavras-passe, crie um objeto PasswordCheckVerifier.

    PasswordCheckVerifier verifier = new PasswordCheckVerifier();
    
  3. Para iniciar uma validação, ligue para PasswordCheckVerifier#createVerification. Este método usa o nome de utilizador e a palavra-passe para calcular os parâmetros para fazer a verificação de palavras-passe.

    PasswordCheckVerification verification = verifier.createVerification("username", "password").get();
    
  4. Crie uma avaliação através dos parâmetros de validação.

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

    As matrizes de bytes lookupHashPrefix e encryptedUserCredentialsHash contêm os parâmetros necessários para iniciar uma verificação de palavra-passe Assessment.

Crie uma avaliação para detetar fugas de palavras-passe

Use o método projects.assessments.create.

Antes de usar qualquer um dos dados do pedido, faça as seguintes substituições:

  • PROJECT_ID: o ID do seu Google Cloud projeto
  • LOOKUP_HASH_PREFIX: prefixo do prefixo do hash SHA-256 do nome de utilizador
  • ENCRYPTED_USER_CREDENTIALS_HASH: hash Scrypt de credenciais de utilizador encriptadas

Método HTTP e URL:

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

Corpo JSON do pedido:

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

Para enviar o seu pedido, escolha uma destas opções:

curl

Guarde o corpo do pedido num ficheiro com o nome request.json, e execute o seguinte comando:

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

Guarde o corpo do pedido num ficheiro com o nome request.json, e execute o seguinte comando:

$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

Deve receber uma resposta JSON semelhante à seguinte:

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

Valide credenciais roubadas a partir de uma avaliação

Da resposta da avaliação, extraia os campos reEncryptedUserCredentials e encryptedLeakMatchPrefixes e transmita-os ao objeto de validação para determinar se as credenciais foram roubadas ou não.

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

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

Exemplo de código

Node.js (TypeScript)

Para saber como implementar a deteção de fugas de palavras-passe através do Node.js (TypeScript), consulte o exemplo de código TypeScript no GitHub.

Java

Para se autenticar no reCAPTCHA, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.


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

Contentor Docker

Para verificar se as credenciais são divulgadas, envie de forma segura o par de credenciais de nome de utilizador e palavra-passe para o contentor através de uma ligação localhost ou configurando o HTTPS no contentor. Em seguida, o contentor encripta estas credenciais antes de fazer um pedido de API ao reCAPTCHA e valida o resultado reencriptado localmente.

Para enviar pedidos para o contentor Docker, conclua os seguintes passos:

  1. Configure o Docker.
  2. Prepare um ambiente para o contentor Docker.
  3. Crie e execute o contentor.
  4. Enviar pedidos HTTP para o contentor.
  5. Interprete o veredito e tome medidas.

Prepare-se para executar o contentor do Docker

  1. Escolha uma estratégia de autenticação.

    O contentor suporta a definição de Credenciais padrão da aplicação ou pode aceitar uma chave da API para autenticação.

  2. Configure o contentor da PLD para ser executado com HTTPS ou num modo de demonstração apenas localhost.

    Uma vez que o contentor aceita credenciais confidenciais do utilizador final (nomes de utilizador e palavras-passe), tem de ser executado com HTTPS ou num modo de demonstração apenas para localhost. Para orientações sobre a configuração HTTPS, consulte o README no GitHub.

Os passos seguintes usam a autenticação da chave da API e executam o cliente no modo de demonstração apenas no localhost.

Crie e execute o contentor Docker

  1. Clone o repositório:

    git clone github.com/GoogleCloudPlatform/reCAPTCHA-PLD
    
  2. Crie o contentor:

    docker build . -t pld-local
    
  3. Inicie o contentor:

    docker run --network host \
    -e RECAPTCHA_PROJECT_ID=PROJECT_ID \
    -e GOOGLE_CLOUD_API_KEY=API_KEY \
    pld-local
    

O contentor é iniciado e começa a publicar pedidos na porta 8080 de localhost.

Envie pedidos de localhost

Antes de usar qualquer um dos dados do pedido, faça as seguintes substituições:

  • LEAKED_USERNAME: nome de utilizador do par de credenciais roubadas.
  • LEAKED_PASSWORD: palavra-passe do par de credenciais roubadas.

Método HTTP e URL:

POST http://localhost:8080/createAssessment/

Corpo JSON do pedido:

{
    "username":"LEAKED_USERNAME",
    "password":"LEAKED_PASSWORD"
}

Para enviar o seu pedido, escolha uma destas opções:

curl

Guarde o corpo do pedido num ficheiro com o nome request.json, e execute o seguinte comando:

curl -X POST \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"http://localhost:8080/createAssessment/"

PowerShell

Guarde o corpo do pedido num ficheiro com o nome request.json, e execute o seguinte comando:

$headers = @{  }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "http://localhost:8080/createAssessment/" | Select-Object -Expand Content

Deve receber uma resposta JSON semelhante à seguinte:


  { "leakedStatus":"LEAKED" }


 OR


  { "leakedStatus":"NO_STATUS" }

Interprete o veredito e tome medidas

A resposta da avaliação mostra se as credenciais foram roubadas e fornece-lhe informações que pode usar para tomar as medidas adequadas para proteger os seus utilizadores.

A tabela seguinte lista as ações recomendadas que pode realizar quando é detetada uma palavra-passe divulgada:

Palavra-passe divulgada detetada Ações para proteger o utilizador
Durante o início de sessão
  • Rejeitar e exigir que o cliente escolha uma palavra-passe diferente e acionar um desafio de MFA, se possível.
  • Lembre o utilizador de usar palavras-passe únicas em todas as contas.
  • Exija palavras-passe fortes no seu site.
  • Peça ao utilizador para ativar a autenticação multifator (MFA) se não a estiver a usar.
Durante a criação da conta ou a reposição da palavra-passe
  • Exigir que o utilizador altere a palavra-passe.
  • Acionar um fluxo de autenticação multifator (MFA).

Se ainda não estiver a usar um fornecedor de MFA no seu site, pode usar a capacidade de MFA do reCAPTCHA.

O que se segue?