Em uma frase
TOTP é um algoritmo que gera um código numérico temporário e em constante mudança a partir de um segredo compartilhado e da hora atual, usado como um segundo fator para fazer login.
O problema que ele resolve
Vamos ser sinceros: senhas são um mal necessário. Nós as esquecemos, as reutilizamos, e os atacantes são deprimentemente bons em roubá-las através de phishing, vazamentos de bancos de dados e a boa e velha adivinhação. Confiar apenas em uma senha é como deixar a porta da frente trancada, mas colocar a chave debaixo do capacho.
É aqui que entra a Autenticação de Múltiplos Fatores (MFA), e sua variação mais comum, a Autenticação de Dois Fatores (2FA). A ideia é provar sua identidade com mais do que apenas algo que você sabe (uma senha). Você também precisa de algo que você tem (como seu celular) ou algo que você é (como sua impressão digital).
No início, o 2FA muitas vezes significava receber um código via SMS. Isso era melhor que nada, mas é vulnerável a ataques de "SIM swapping", onde um golpista convence sua operadora de celular a transferir seu número para o telefone dele. De repente, ele está recebendo seus códigos 2FA. Nada bom.
Aí entram os autenticadores baseados em app. Em vez de depender da segurança instável da rede telefônica, um app no seu dispositivo pode gerar códigos localmente. Mas como o seu app Google Authenticator sabe como gerar um código para sua conta do GitHub? E como o seu Microsoft Authenticator sabe como falar com o seu Dropbox?
Todos eles falam a mesma língua padrão e aberta: TOTP, a Senha de Uso Único Baseada em Tempo. O TOTP é o herói anônimo que desacopla seu segundo fator de qualquer empresa específica. É um padrão aberto e interoperável que permite que qualquer app compatível funcione com qualquer serviço compatível. É a evolução de um padrão anterior chamado HOTP (que era baseado em um simples contador), mas ao usar o tempo como a peça móvel, o TOTP tornou-se muito mais fácil de usar.
Como funciona por debaixo dos panos
TOTP parece mágica. Você escaneia um QR code uma vez, e pelo resto da vida, seu celular e um servidor do outro lado do mundo conseguem concordar no mesmo número de seis dígitos a cada 30 segundos, sem nunca mais precisarem conversar. Não é mágica, é apenas criptografia bem inteligente.
Vamos detalhar a receita.
O Segredo Compartilhado: A Chave para o Reino
Tudo começa com um segredo. Quando você ativa o 2FA em um serviço, o servidor gera uma chave secreta e aleatória (por exemplo, 160 bits de pura aleatoriedade). Este segredo é a única coisa que tanto você quanto o servidor precisam saber. Toda a segurança do sistema depende de mantê-lo em segredo.
Claro, uma sequência de 160 bits aleatórios não é muito amigável para o usuário. Então, para nós, humanos, ele é codificado em um formato chamado Base32. Diferente do seu primo Base64, o Base32 usa um alfabeto menor que não diferencia maiúsculas de minúsculas e evita caracteres ambíguos como 1 e l, ou 0 e O. Isso torna possível (embora ainda seja um saco) digitar manualmente se você não puder escanear o QR code.
Um segredo Base32 típico se parece com isto: JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXP
A maneira mais comum de colocar este segredo no seu app autenticador é através de um QR code que codifica uma URI especial:
otpauth://totp/FlowingDev:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=FlowingDev
Seu app escaneia isso, salva o emissor (FlowingDev), o nome da conta (user@example.com) e, o mais importante, o secret. O aperto de mão está completo.
A Peça Móvel: O Tempo
O "T" em TOTP significa Time-Based (Baseado em Tempo). Este é o ingrediente crucial que faz o código mudar. Mas o sistema não usa a hora exata até o milissegundo — isso seria impossível de sincronizar. Em vez disso, ele usa um passo de tempo discreto.
A fórmula é simples:
PassoDeTempo = floor(TempoUnixAtual / 30)
- TempoUnixAtual: O número de segundos que se passaram desde 1º de janeiro de 1970 (a Época Unix ou Unix Epoch).
- / 30: O passo de tempo é quase universalmente de 30 segundos.
Este cálculo resulta em um número inteiro que só muda a cada 30 segundos. Às 10:00:00, o PassoDeTempo é um valor T. Às 10:00:29, ainda é T. Mas às 10:00:30, ele incrementa para T+1. Este PassoDeTempo é a "mensagem" que vamos autenticar.
A Mágica Criptográfica: HMAC-SHA1
Agora combinamos o segredo estático com o passo de tempo móvel. Isso é feito usando uma primitiva criptográfica chamada HMAC (Hash-based Message Authentication Code, ou Código de Autenticação de Mensagem Baseado em Hash).
Resultado_HMAC = HMAC-SHA1(ChaveSecreta, PassoDeTempo)
Pense no HMAC como uma forma de criar uma assinatura segura. Ele pega nossa chave secreta e os dados que queremos assinar (o PassoDeTempo) e mistura tudo usando uma função de hash — neste caso, o venerável SHA-1.
A saída é um hash de 20 bytes (160 bits). É uma longa string hexadecimal que é completamente única para aquele segredo específico e aquele passo de tempo específico. Mude um bit do segredo ou espere 30 segundos para o passo de tempo mudar, e você obterá um hash completamente diferente.
Embora o SHA-1 tenha fraquezas conhecidas para outros fins, como assinar certificados, ele ainda é considerado perfeitamente seguro quando usado dentro da construção HMAC. Muitas implementações modernas estão migrando para HMAC-SHA256 ou HMAC-SHA512 por precaução.
O Truncamento: Chegando aos Seis Dígitos
Uma string hexadecimal de 20 bytes não é um código de seis dígitos fácil de usar. O passo final é "truncar dinamicamente" este hash para um número que possamos realmente usar.
- Encontre o Offset: Olhe para os últimos 4 bits (nibble) do resultado HMAC de 20 bytes. Isso nos dá um número entre 0 e 15. Este é o nosso
offset. - Pegue 4 Bytes: Começando na posição desse
offsetno hash de 20 bytes, pegue os próximos 4 bytes (32 bits). - Limpe o Bit Mais Significativo: Pegue este bloco de 32 bits e faça um
bitwise ANDcom0x7FFFFFFF. Isso efetivamente se livra do primeiro bit, o que resolve alguns problemas potenciais de inteiros com sinal versus sem sinal e garante que o resultado seja sempre positivo. - Hora do Módulo! Agora você tem um grande inteiro de 31 bits. Para reduzi-lo a 6 dígitos, você aplica o módulo 1.000.000 (
10^6). - Preencha com Zeros: O resultado é o seu código! Se o número for, digamos,
4521, você o preenche com zeros à esquerda para se tornar004521.
É isso! Tanto o seu celular quanto o servidor executam exatamente este mesmo cálculo. Quando você insere o código, o servidor compara o resultado dele com o seu. Para compensar pequenos desvios de relógio entre seu celular e o servidor, o servidor normalmente verificará o código para o passo de tempo atual, o anterior e o seguinte. Se algum deles corresponder, você está dentro.
Histórias do mundo real
A Invasão de Conta do GitHub que Não Aconteceu
Um desenvolvedor, super concentrado, recebe um e-mail que parece exatamente ser do GitHub, alertando sobre um problema de segurança. Em um momento de distração, ele clica no link, cai em um clone pixel-perfect da página de login do GitHub e insere seu nome de usuário e senha. O atacante agora tem suas credenciais. O phisher imediatamente tenta fazer login no GitHub real. Ele insere a senha roubada... e se depara com um prompt: "Por favor, insira seu código de autenticação de dois fatores." O atacante está completamente travado. Ele não tem o celular do desenvolvedor e não tem como gerar o código TOTP. O desenvolvedor, enquanto isso, recebe um e-mail real do GitHub sobre um novo login, percebe seu erro e prontamente muda sua senha.
Lição: O TOTP atua como um firewall crítico. Ele transforma uma violação de senha potencialmente catastrófica em uma tentativa de login falha e inofensiva.
A Emergência de Acesso Offline
Um engenheiro de rede está em um voo para uma conferência. Trinta minutos após a decolagem, ele precisa verificar um sistema de produção crítico. Não há Wi-Fi no avião e zero sinal de celular. Um 2FA baseado em SMS ou push seria inútil. Mas seu painel é protegido com TOTP. Ele abre seu laptop, acessa a página de login, abre o app autenticador em seu celular e digita o código de seis dígitos. O app não precisa de nenhuma conexão com a internet; sua matemática é autocontida, dependendo apenas do segredo compartilhado e do relógio interno do celular. Ele faz login и resolve o problema antes mesmo de as comissárias de bordo começarem a servir as bebidas.
Lição: A capacidade do TOTP de funcionar completamente offline o torna incrivelmente robusto e confiável para acesso crítico, não importa onde você esteja.
A Dor de Cabeça da Migração Multiplataforma... Resolvida
Um usuário de longa data do Android decide mudar para um iPhone. Ele abre o Google Authenticator e fica horrorizado ao descobrir que não há um botão simples de "sincronizar com meu novo celular". Ele tem mais de 30 contas configuradas, e a ideia de passar pelo processo de redefinição do 2FA para cada uma delas é um pesadelo. Mas então ele se lembra de sua política de segurança pessoal: para cada novo serviço, ele tem salvado o QR code inicial como um print em seu gerenciador de senhas criptografado. Ele instala um novo app autenticador em seu iPhone, abre seu gerenciador de senhas e, um por um, reescaneia os QR codes salvos. Em dez minutos, todas as 30 contas são migradas e estão funcionando perfeitamente.
Lição: O segredo TOTP (como uma string Base32 ou QR code) é a verdadeira chave. Ser independente de qualquer app autenticador específico, fazendo backup seguro de seus segredos, lhe dá verdadeira posse e portabilidade.
Erros e armadilhas comuns
- Tratar o segredo de forma casual. O QR code ou a string Base32 que você recebe na configuração é a chave secreta. Se um atacante o obtiver, ele poderá gerar códigos válidos para sempre. Não tire print e o deixe na sua área de trabalho, não o envie por e-mail para si mesmo e não o armazene em um arquivo de texto simples. Trate-o como uma master password.
- Esquecer de salvar os códigos de recuperação. Ao ativar o 2FA, quase todos os serviços fornecerão um conjunto de códigos de recuperação de uso único. IMPRIMA-OS. Salve-os em um lugar seguro (um cofre de verdade ou, no mínimo, seu gerenciador de senhas). Se você perder seu celular, esses códigos são sua única maneira de voltar à sua conta sem um processo de suporte doloroso.
- Assumir que seu app autenticador tem backup. Muitos apps autenticadores simples (como o Google Authenticator original) armazenam segredos apenas naquele dispositivo. Se o celular for perdido ou formatado, os segredos se foram para sempre. Use um app que ofereça sincronização segura e criptografada na nuvem (como Authy ou 1Password) ou seja disciplinado ao fazer backup de seus segredos manualmente.
- Ignorar o desvio do relógio. O TOTP é baseado no tempo. Se o relógio do seu celular estiver adiantado ou atrasado em mais de um minuto ou dois em relação à hora real, os códigos que ele gera serão rejeitados. Sempre configure seu celular e computador para "Definir hora automaticamente". Quase sempre é o culpado quando códigos válidos de repente param de funcionar.
Por que isso deve estar no seu radar
Se você é um desenvolvedor construindo qualquer sistema que tenha contas de usuário, você deveria estar implementando MFA, e o TOTP é a melhor opção de padrão aberto para 2FA baseado em app. É mais seguro que SMS e mais aberto que sistemas de notificação push proprietários. Entender como gerar um segredo, criar uma URI otpauth:// e validar um token recebido é uma habilidade fundamental para construir aplicações seguras.
Mesmo que você nunca implemente um sistema TOTP, você é um usuário deles em plataformas como AWS, Cloudflare, GitHub e npm. Saber como a mágica funciona por debaixo dos panos te capacita a usá-lo com mais segurança. Ajuda você a entender a importância de proteger o segredo inicial, salvar seus códigos de recuperação e escolher o app autenticador certo para suas necessidades. Ele desmistifica o pequeno número de seis dígitos que fica entre seus dados e os caras maus.
Aprofunde-se
- RFC 6238: Time-Based One-Time Password Algorithm — A especificação oficial para o TOTP.
- RFC 4226: HMAC-Based One-Time Password Algorithm — A especificação para o HOTP, a base sobre a qual o TOTP é construído.
- RFC 4648: The Base16, Base32, and Base64 Data Encodings — A especificação que define a codificação Base32 usada para compartilhar segredos.
- Key URI Format · google/google-authenticator Wiki — O padrão de-facto para a URI
otpauth://usada em QR codes. - Time-based One-time Password - Wikipedia — Uma visão geral de alto nível e histórica do algoritmo.