Autenticação segura do usuário

Para proteger seu sistema de autenticação no Android, considere abandonar um modelo baseado em senhas, principalmente para contas sensíveis, como as bancárias e de e-mail dos usuários. Lembre-se de que alguns apps instalados pelos usuários podem não ter as melhores intenções e tentar fazer phishing com eles.

Além disso, não presuma que apenas usuários autorizados vão usar o dispositivo. O roubo de smartphones é um problema comum, e os criminosos visam dispositivos desbloqueados para lucrar diretamente com dados de usuários ou apps financeiros. Sugerimos que todos os apps sensíveis implementem um tempo limite de autenticação razoável (15 minutos?) com verificação biométrica e exijam autenticação adicional antes de ações sensíveis, como transferências de dinheiro.

Caixa de diálogo de autenticação biométrica

A biblioteca Biometrics oferece um conjunto de funções para mostrar uma solicitação de autenticação biométrica, como reconhecimento facial ou de impressão digital. No entanto, os comandos biométricos podem ser configurados para voltar ao LSKF, que tem riscos conhecidos de shoulder surfing. Para apps sensíveis, recomendamos não usar o PIN como alternativa à biometria. Depois de esgotar as tentativas biométricas, os usuários podem esperar ou fazer login novamente com uma senha ou redefinir as contas. A redefinição de conta precisa exigir fatores que não sejam facilmente acessíveis no dispositivo (prática recomendada abaixo).

Como isso ajuda a reduzir fraudes e roubos de smartphone

Um caso de uso específico que pode ajudar a evitar fraudes é solicitar autenticação biométrica no app antes de uma transação. Quando os usuários querem fazer uma transação financeira, a caixa de diálogo biométrica aparece para verificar se é realmente o usuário pretendido que está fazendo a transação. Essa prática recomendada protege contra o roubo de um dispositivo por um invasor, mesmo que ele saiba ou não o LSKF, já que ele precisará provar que é o proprietário do dispositivo.

Para níveis adicionais de segurança, recomendamos que os desenvolvedores de apps solicitem a autenticação biométrica Classe 3 e usem CryptoObject para transações bancárias e financeiras.

Implementação

  1. Inclua a biblioteca androidx.biometric.
  2. Inclua a caixa de diálogo de login por biometria na atividade ou no fragmento que contém a lógica que você quer que o usuário seja autenticado.

Kotlin

private var executor: Executor? = null
private var biometricPrompt: BiometricPrompt? = null
private var promptInfo: BiometricPrompt.PromptInfo? = null

fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_login)
  executor = ContextCompat.getMainExecutor(this)
  biometricPrompt = BiometricPrompt(this@MainActivity,
    executor, object : AuthenticationCallback() {
      fun onAuthenticationError(
        errorCode: Int,
        @NonNull errString: CharSequence
      ) {
        super.onAuthenticationError(errorCode, errString)
        Toast.makeText(
          getApplicationContext(),
          "Authentication error: $errString", Toast.LENGTH_SHORT
        )
          .show()
      }

      fun onAuthenticationSucceeded(
        @NonNull result: BiometricPrompt.AuthenticationResult?
      ) {
        super.onAuthenticationSucceeded(result)
        Toast.makeText(
          getApplicationContext(),
          "Authentication succeeded!", Toast.LENGTH_SHORT
        ).show()
      }

      fun onAuthenticationFailed() {
        super.onAuthenticationFailed()
        Toast.makeText(
          getApplicationContext(), "Authentication failed",
          Toast.LENGTH_SHORT
        )
          .show()
      }
    })
  promptInfo = Builder()
    .setTitle("Biometric login for my app")
    .setSubtitle("Log in using your biometric credential")
    .setNegativeButtonText("Use account password")
    .build()

  // Prompt appears when user clicks "Log in".
  // Consider integrating with the keystore to unlock cryptographic operations,
  // if needed by your app.
  val biometricLoginButton: Button = findViewById(R.id.biometric_login)
  biometricLoginButton.setOnClickListener { view ->
    biometricPrompt.authenticate(
      promptInfo
    )
  }
}

Java

private Executor executor;
private BiometricPrompt biometricPrompt;
private BiometricPrompt.PromptInfo promptInfo;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    executor = ContextCompat.getMainExecutor(this);
    biometricPrompt = new BiometricPrompt(MainActivity.this,
            executor, new BiometricPrompt.AuthenticationCallback() {
        @Override
        public void onAuthenticationError(int errorCode,
                @NonNull CharSequence errString) {
            super.onAuthenticationError(errorCode, errString);
            Toast.makeText(getApplicationContext(),
                "Authentication error: " + errString, Toast.LENGTH_SHORT)
                .show();
        }

        @Override
        public void onAuthenticationSucceeded(
                @NonNull BiometricPrompt.AuthenticationResult result) {
            super.onAuthenticationSucceeded(result);
            Toast.makeText(getApplicationContext(),
                "Authentication succeeded!", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onAuthenticationFailed() {
            super.onAuthenticationFailed();
            Toast.makeText(getApplicationContext(), "Authentication failed",
                Toast.LENGTH_SHORT)
                .show();
        }
    });

    promptInfo = new BiometricPrompt.PromptInfo.Builder()
            .setTitle("Biometric login for my app")
            .setSubtitle("Log in using your biometric credential")
            .setNegativeButtonText("Use account password")
            .build();

    // Prompt appears when the user clicks "Log in".
    // Consider integrating with the keystore to unlock cryptographic operations,
    // if needed by your app.
    Button biometricLoginButton = findViewById(R.id.biometric_login);
    biometricLoginButton.setOnClickListener(view -> {
            biometricPrompt.authenticate(promptInfo);
    });
}

Práticas recomendadas

Recomendamos que você comece com o codelab para saber mais sobre biometria.

Dependendo dos seus casos de uso, é possível implementar a caixa de diálogo com ou sem uma ação explícita do usuário. Para evitar fraudes, recomendamos que você adicione a caixa de diálogo biométrica com ação explícita do usuário em todas as transações. Entendemos que adicionar autenticação pode causar atrito na UX, mas, devido à natureza das informações processadas em uma transação bancária e ao fato de a autenticação biométrica ser mais suave do que outros métodos, achamos necessário adicionar esse nível de navegação.

Saiba mais sobre a autenticação biométrica.

Chaves de acesso

As chaves de acesso são uma alternativa mais segura e fácil de usar do que as senhas. As chaves de acesso usam criptografia de chave pública para permitir que os usuários façam login em apps e sites usando o mecanismo de bloqueio de tela do dispositivo, como impressão digital ou reconhecimento facial. Isso evita que o usuário precise lembrar e gerenciar senhas, além de oferecer uma segurança muito maior.

As chaves de acesso atendem aos requisitos de autenticação multifator em uma única etapa, substituindo senhas e códigos OTP para oferecer proteção robusta contra ataques de phishing e evitar a dificuldade de usar senhas de uso único baseadas em SMS ou apps. Como as chaves de acesso são padronizadas, uma única implementação permite uma experiência sem senha em todos os dispositivos, navegadores e sistemas operacionais dos usuários.

No Android, as chaves de acesso são compatíveis com a biblioteca Credential Manager do Jetpack, que unifica os principais métodos de autenticação, incluindo chaves de acesso, senhas e login federado (como o recurso Fazer login com o Google).

Como isso ajuda a reduzir fraudes

As chaves de acesso protegem você contra ataques de phishing porque só funcionam nos apps e sites registrados.

O componente principal de uma chave de acesso é uma chave privada criptográfica. Normalmente, essa chave privada fica apenas nos seus dispositivos, como laptops ou smartphones, e é sincronizada entre eles por provedores de credenciais (também conhecidos como gerenciadores de senhas), como o Gerenciador de senhas do Google. Somente a chave pública correspondente é salva pelo serviço on-line quando uma chave de acesso é criada. Durante o login, o serviço usa a chave privada para assinar um desafio da chave pública. Isso só pode vir de um dos seus dispositivos. Além disso, para que isso aconteça, você precisa desbloquear seu dispositivo ou armazenamento de credenciais, o que impede logins não autorizados (por exemplo, de um smartphone roubado).

Para evitar o acesso não autorizado em caso de roubo de um dispositivo desbloqueado, as chaves de acesso precisam ser combinadas com um período de tempo limite de autenticação razoável. Um invasor que rouba um dispositivo não pode usar um aplicativo só porque o usuário anterior estava conectado. Em vez disso, as credenciais precisam expirar em intervalos regulares (por exemplo, a cada 15 minutos), e os usuários precisam verificar a identidade com a reautenticação do bloqueio de tela.

Se o smartphone for roubado, as chaves de acesso vão proteger você, porque os ladrões não podem roubar suas senhas para usar em outros dispositivos. As chaves de acesso são específicas de cada dispositivo. Se você usa o Gerenciador de senhas do Google e seu smartphone for roubado, faça login na sua Conta do Google em outro dispositivo (como um computador) e saia remotamente do smartphone roubado. Isso torna o Gerenciador de senhas do Google no smartphone roubado inutilizável, incluindo as chaves de acesso salvas.

No pior cenário, se o dispositivo roubado não for recuperado, as chaves de acesso serão sincronizadas novamente com o novo dispositivo pelo provedor de credenciais que criou e sincronizou a chave de acesso. Por exemplo, o usuário pode ter escolhido o Gerenciador de senhas do Google para criar a chave de acesso, e é possível acessar a chave em um novo dispositivo fazendo login novamente na Conta do Google e fornecendo o bloqueio de tela do dispositivo anterior.

Saiba mais no artigo Segurança das chaves de acesso no Gerenciador de senhas do Google.

Implementação

As chaves de acesso são aceitas em dispositivos com Android 9 (nível 28 da API) ou versões mais recentes. As senhas e o recurso "Fazer login com o Google" são compatíveis a partir do Android 4.4. Para começar a usar chaves de acesso, siga estas etapas:

  1. Siga o codelab do Gerenciador de credenciais para entender como implementar chaves de acesso.
  2. Leia as diretrizes de design da experiência do usuário com chaves de acesso. Este documento mostra quais fluxos são recomendados para seu caso de uso.
  3. Estude o Gerenciador de credenciais seguindo o guia.
  4. Planeje a implementação do Credential Manager e das chaves de acesso no seu app. Planeje adicionar suporte para Digital Asset Links.

Consulte nossa documentação para desenvolvedores para mais detalhes sobre como criar, registrar e autenticar com chaves de acesso.

Redefinição segura da conta

Um invasor não autorizado com acesso a um dispositivo desbloqueado (como quando um smartphone é roubado) vai tentar acessar apps sensíveis, especialmente de banco ou dinheiro. Se o app implementar a verificação biométrica, o invasor tentará redefinir a conta para entrar. É essencial que o fluxo de redefinição de conta não dependa apenas de informações facilmente acessíveis no dispositivo, como links de redefinição de e-mail ou OTP por SMS.

Confira algumas práticas recomendadas comuns que você pode incorporar ao fluxo de redefinição do seu app:

  • Reconhecimento facial, além do OTP
  • Perguntas de segurança
  • Fatores de conhecimento (como nome de solteira da mãe, cidade de nascimento ou música favorita)
  • Confirmação de identidade com documento

API SMS Retriever

A API SMS Retriever permite fazer a confirmação automática do usuário com base em SMS no seu app Android. Assim, o usuário não precisa digitar os códigos de verificação manualmente. Além disso, essa API não pede ao usuário permissões extras e potencialmente perigosas do app, como RECEIVE_SMS ou READ_SMS. No entanto, o SMS não deve ser usado como a única verificação de usuário para proteger contra acesso local não autorizado ao dispositivo.

Como isso ajuda a reduzir fraudes

Alguns usuários usam códigos SMS como único fator de autenticação, o que facilita a entrada de fraudes.

A API SMS Retriever permite que o app recupere diretamente o código por SMS sem interação do usuário e oferece um nível de proteção contra fraudes.

Implementação

A implementação da API SMS Retriever tem duas partes: Android e servidor.

Android: (guia)

  1. Solicite o número de telefone do usuário.
  2. Inicie o cliente do SMS Retriever.
  3. Envie o número de telefone para seu servidor.
  4. Receber mensagens de verificação.
  5. Envie a OTP para seu servidor.

Servidor: (guia)

  1. Construa uma mensagem de verificação.
  2. Envie a mensagem de verificação por SMS.
  3. Verifique a OTP quando ela for retornada.

Práticas recomendadas

Depois que o app é integrado e o número de telefone do usuário é verificado com a API SMS Retriever, ele tenta receber a senha única. Se isso acontecer, é um sinal forte de que o SMS foi recebido automaticamente no dispositivo. Se não funcionar e o usuário precisar digitar manualmente o OTP, isso pode ser um sinal de alerta de que ele está sofrendo uma fraude.

O SMS não deve ser usado como o único mecanismo de verificação do usuário, já que deixa espaço para ataques locais, como um invasor que rouba um dispositivo desbloqueado ou ataques de clonagem de SIM. Recomendamos usar biometria sempre que possível. Em dispositivos em que sensores biométricos não estão disponíveis, a autenticação do usuário deve depender de pelo menos um fator que não seja facilmente obtido no dispositivo atual.

Saiba mais

Para mais informações sobre práticas recomendadas, consulte os seguintes recursos: