Autenticação em múltiplos fatores
TOTP, chaves de acesso e SMS, e o que cada fator protege de fato.
O problema: a senha sozinha não basta
Senhas vazam: em bancos invadidos, em sites falsos, em máquinas com programas espiões. E são reutilizadas, então a senha que vazou de um fórum abre a conta de e-mail. Ataques que testam listas de senhas vazadas em outros sites (credential stuffing) funcionam justamente por isso.
A autenticação em múltiplos fatores (MFA) exige, além da senha, uma prova de outro tipo:
| Tipo de fator | Exemplos |
|---|---|
| Algo que você sabe | Senha, PIN |
| Algo que você tem | Celular com aplicativo autenticador, chave de segurança, chip do celular |
| Algo que você é | Digital, rosto (normalmente usado para destravar o que você tem) |
Com dois fatores de tipos diferentes, quem tem só a senha vazada não entra. Mas os fatores não são iguais: cada um resiste a ataques diferentes.
TOTP: o código do aplicativo autenticador
O código de 6 dígitos que muda a cada 30 segundos (Google Authenticator, Microsoft Authenticator, 1Password e outros) segue o padrão TOTP (time-based one-time password, RFC 6238).
No cadastro, o servidor gera um segredo aleatório e o mostra num QR code. O aplicativo guarda o segredo. A partir daí, os dois lados calculam o mesmo código, sem conversar:
passo = segundos desde 1970 / 30 (muda a cada 30 s)
código = HMAC-SHA1(segredo, passo), reduzido a 6 dígitosO QR code contém uma URI como esta, gerada no teste com a biblioteca pyotp:
otpauth://totp/Loja:ana%40exemplo.com?secret=YOMG2QNFELC6B3L3C3REZ22ZUKUHXRXO&issuer=LojaO segredo vai em base32. Ele é tão sensível quanto uma senha, e o servidor precisa guardá-lo de forma recuperável (criptografado, e não com hash), porque precisa recalcular os códigos.
Como os relógios do celular e do servidor nunca estão perfeitamente iguais, o servidor costuma aceitar o código do passo anterior e do seguinte. E, para o código ser realmente de uso único, guarda o último passo aceito e recusa qualquer código desse passo ou de antes.
O limite de tentativas é obrigatório
Um código de 6 dígitos tem um milhão de combinações. Com a janela de três passos, três códigos valem ao mesmo tempo: cada chute tem 3 chances em um milhão.
Parece pouco, até medir. Montamos uma rota que confere o código TOTP sem limite de tentativas e um atacante com 64 conexões chutando códigos aleatórios, os dois na mesma máquina:
| Rodada | Tentativas até acertar | Tempo |
|---|---|---|
| 1 | 16.056 | 3,6 s |
| 2 | 140.598 | 37,3 s |
| 3 | 274.138 | 81,3 s |
Entre 3.400 e 4.500 tentativas por segundo, e o código caiu nas três rodadas, em menos de um minuto e meio. Pela rede, o atacante faria menos tentativas por segundo, mas a conta continua a favor dele: a média esperada é de 333 mil tentativas.
Com um limite de 5 tentativas a cada 15 minutos por conta, as mesmas 333 mil tentativas levariam cerca de 690 dias. O limite transforma o código de 6 dígitos de inútil em eficaz. Ele precisa valer por conta, e não só por IP, porque o atacante pode distribuir as tentativas entre muitos endereços.
O ponto fraco dos códigos: sites falsos
TOTP, SMS e códigos por e-mail têm uma fraqueza em comum: o usuário digita o código. Um site falso, idêntico ao verdadeiro, pede a senha e o código, e os repassa ao site verdadeiro na hora, dentro dos 30 segundos. Ferramentas de phishing automatizam esse repasse e capturam até o cookie de sessão. O segundo fator não ajuda: o usuário o entregou ao atacante.
Chaves de acesso: o fator que resiste a sites falsos
As chaves de acesso (passkeys), baseadas no padrão WebAuthn, funcionam de outro jeito. No cadastro, o dispositivo (celular, computador ou chave de segurança) cria um par de chaves para aquele site. A chave privada nunca sai do dispositivo. No login, o servidor manda um desafio, o dispositivo o assina, e o servidor confere com a chave pública.
O ponto decisivo: o navegador amarra cada chave ao domínio do site, e se recusa a usá-la em outro domínio. O usuário não tem como entregar a assinatura a um site falso, mesmo se cair no golpe.
Testamos num Chrome real, com um autenticador virtual. A chave foi criada em loja.test. Depois, a mesma página foi servida em 1oja.test (com o número 1 no lugar da letra l):
| Situação | Resultado |
|---|---|
Cadastro e login em loja.test | Assinatura conferida pelo servidor |
Site falso pede uma assinatura para loja.test | SecurityError: The RP ID "loja.test" is invalid for this domain |
| Site falso pede uma assinatura para o próprio domínio | NotAllowedError: não existe chave para 1oja.test |
Nas duas tentativas do site falso, o navegador não produziu nenhuma assinatura. Com TOTP, o mesmo site falso teria recebido o código digitado pelo usuário.
As chaves de acesso podem substituir a senha inteira: o dispositivo confere a digital ou o PIN (algo que você é ou sabe) e guarda a chave (algo que você tem). São dois fatores numa só ação.
SMS e e-mail
| Fator | O que protege | Fraquezas |
|---|---|---|
| Código por SMS | Senha vazada | Troca fraudulenta do chip (SIM swap), interceptação, phishing com repasse |
| Código por e-mail | Senha vazada | Quem tem o e-mail tem tudo; phishing com repasse |
| TOTP | Senha vazada, SIM swap | Phishing com repasse; segredo vazado do servidor |
| Chave de acesso | Senha vazada, SIM swap, phishing | Perder todos os dispositivos sem uma forma de recuperação |
O SMS é o fator mais fraco, e entidades como o NIST desaconselham o seu uso como única opção. Ainda assim, um SMS barra a grande maioria dos ataques automatizados com senhas vazadas. Para muitos usuários, a escolha real é entre SMS e nada.
Recuperação: o lado esquecido
O usuário troca de celular, perde o aparelho ou apaga o aplicativo. Sem um plano, a conta fica inacessível, e o suporte recebe o pedido "desativa o MFA para mim". Se o suporte desativa sem conferir a identidade, essa vira a porta de entrada do atacante.
As saídas usuais: códigos de recuperação de uso único, mostrados no cadastro e guardados com hash; cadastro de mais de um fator (duas chaves de acesso, ou chave e TOTP); e um processo de recuperação pelo suporte tão rigoroso quanto o próprio login.
Por que isso importa quando a IA escreve o código
Um assistente que implementa "login com código do Google Authenticator" costuma acertar o cálculo e errar o resto:
- Nenhum limite de tentativas na rota que confere o código.
- O mesmo código aceito duas vezes dentro dos 30 segundos.
- Uma janela grande demais, aceitando códigos de minutos atrás.
- O segredo TOTP guardado em texto puro na tabela de usuários.
- Códigos de recuperação guardados em texto puro, ou reutilizáveis.
- Comparação com
==em vez de comparação em tempo constante. - Trocar o e-mail ou desativar o MFA sem pedir o segundo fator.
O próximo nível compara os fatores em detalhe, os fluxos de cadastro e de recuperação, e quando exigir o segundo fator.
Prompts para aprofundar
Ao abrir no ChatGPT ou no Claude, o prompt é enviado ao serviço escolhido pela URL e também fica copiado na sua área de transferência.
Autenticação em múltiplos fatores em cinco minutos
Explique em no máximo cinco minutos de leitura o que é autenticação em múltiplos fatores, para alguém que já fez um login com senha, mas nunca implementou um segundo fator. Cubra só o essencial: os tipos de fator, como funciona o código do aplicativo autenticador, por que as chaves de acesso resistem a sites falsos, o que o SMS protege e o que não protege, e para que servem os códigos de recuperação. Use o exemplo de uma loja online. No final, me faça três perguntas curtas para eu verificar se entendi, e corrija as minhas respostas.
TOTP por dentro
Quero entender como funciona o TOTP, o código de 6 dígitos dos aplicativos autenticadores. Aja como um mentor e vá por etapas, esperando a minha resposta em cada uma: 1. O segredo compartilhado, o QR code e a URI otpauth. 2. Como o passo de 30 segundos e o HMAC geram o código, com um exemplo numérico. 3. Por que o servidor aceita uma janela de passos, e o risco de uma janela grande. 4. Como garantir que o mesmo código não seja aceito duas vezes. 5. Por que um código de 6 dígitos sem limite de tentativas é inseguro, com a conta da probabilidade. Em cada etapa, me faça uma pergunta para verificar se entendi antes de seguir.
Chaves de acesso e phishing
Quero entender por que as chaves de acesso (passkeys, WebAuthn) resistem a sites falsos e os códigos digitados não. Explique: 1. Como funciona um ataque de phishing com repasse em tempo real contra TOTP e SMS. 2. O par de chaves criado no cadastro e o desafio assinado no login. 3. O papel do navegador ao amarrar a chave ao domínio (RP ID) e incluir a origem na assinatura. 4. Por que o usuário não consegue entregar a chave a um site falso, mesmo caindo no golpe. 5. O que ainda pode dar errado: sessão roubada depois do login, recuperação fraca, perda dos dispositivos. Depois me descreva três ataques e pergunte quais fatores resistem a cada um. Corrija as minhas respostas.
Recuperação de contas com MFA
Quero entender como recuperar o acesso de quem perdeu o segundo fator sem abrir uma porta para atacantes. Explique: 1. Códigos de recuperação: como gerar, mostrar e guardar. 2. Cadastro de mais de um fator. 3. Recuperação pelo suporte e os golpes de engenharia social contra ela. 4. A espera com aviso antes de remover um fator. 5. Por que remover o MFA só com um link no e-mail desfaz a proteção. Depois me descreva duas situações de usuário que perdeu o celular e pergunte como eu resolveria cada uma com segurança.