TOTP no app autenticador: janela de tempo, desvio de relógio e segredo compartilhado
O que as RFCs 6238 e 4226 definem sobre passo de tempo, tolerância de relógio e limite de tentativas, e por que o TOTP tira o segundo fator da operadora sem resistir a phishing.
Foto: Chris Ried, Unsplash
Os seis dígitos que aparecem no aplicativo autenticador e mudam sozinhos a cada meio minuto costumam ser tratados como caixa-preta. Não são. O TOTP, sigla em inglês para senha de uso único baseada em tempo, é um algoritmo curto e publicado, com parâmetros que quem integra escolhe, e cada parâmetro troca segurança por conveniência de um jeito que a própria norma explicita.
Entender essa troca importa porque o TOTP é a alternativa mais direta ao código por SMS. Ele não depende da operadora, então não cai no golpe de troca de chip descrito em SIM swap e o limite do SMS. Em compensação, traz três problemas próprios: o verificador guarda um segredo simétrico por usuário, os relógios dos dois lados precisam combinar, e o código continua sendo digitável numa página falsa. A matemática está nas RFCs 6238 e 4226 do IETF, a organização que padroniza protocolos da internet, e os requisitos de quem verifica estão no guia do NIST, instituto de padrões dos Estados Unidos.
O algoritmo, em uma frase
A RFC 6238, de maio de 2011, define TOTP como uma variante do HOTP, a senha de uso único baseada em contador. O contador vira um valor T derivado do relógio: o resultado inteiro da divisão do tempo Unix atual, menos um instante inicial T0, pelo passo de tempo X. O documento fixa como padrão X igual a 30 segundos e T0 igual a zero, a própria época Unix, e os dois parâmetros são combinados entre gerador e verificador no provisionamento.
O HOTP está na RFC 4226, de dezembro de 2005: o valor é uma truncagem dinâmica do HMAC-SHA-1 da chave com o contador, reduzido por módulo a uma quantidade fixa de dígitos. A norma exige no mínimo seis dígitos e diz que, conforme o requisito de segurança, sete ou mais devem ser considerados. Ela também determina que o segredo compartilhado tenha pelo menos 128 bits, recomendando 160. A RFC 6238 permite trocar o SHA-1 por HMAC-SHA-256 ou HMAC-SHA-512.
A janela: o que a norma recomenda e o que ela avisa
Aqui está o parágrafo que decide o desenho. A RFC 6238 observa que o verificador não conhece o instante exato em que o código foi gerado e tipicamente usa o instante de recebimento. Por causa da latência de rede, um código gerado no fim de uma janela muito provavelmente chega na janela seguinte.
A conclusão do documento é dupla. O verificador deve definir uma política de janela aceitável de atraso de transmissão e comparar o código não só com o instante de recebimento, mas também com instantes passados dentro desse atraso. E, em seguida, o aviso: uma janela de atraso maior expõe uma janela maior de ataque, com a recomendação explícita de permitir no máximo um passo de tempo como atraso de rede.
Sobre o tamanho do passo, a mesma seção recomenda 30 segundos como padrão, escolhido como equilíbrio entre segurança e usabilidade, e lista as duas consequências de aumentá-lo: um código válido por mais tempo fica exposto por mais tempo a quem o interceptar, e o usuário espera mais pelo próximo depois de um uso bem-sucedido. A norma fecha o reuso exigindo que o verificador não aceite uma segunda apresentação do mesmo código depois de validada a primeira.
O desvio de relógio, com a conta da própria RFC
Como os relógios derivam, a RFC 6238 recomenda que o validador tenha um limite explícito de quantos passos de tempo o gerador pode estar fora de sincronia, para a frente e para trás. O exemplo numérico é da própria norma: com passo de 30 segundos, se o validador aceita apenas dois passos para trás, o desvio máximo de tempo decorrido fica em torno de 89 segundos, sendo 29 segundos dentro do passo calculado e 60 segundos dos dois passos anteriores. Nessa configuração o validador faz três validações, uma contra o tempo atual e duas para trás.
A norma acrescenta dois refinamentos. Ao validar com sucesso, o servidor pode registrar o desvio detectado, em número de passos, e usá-lo para ajustar a comparação nas próximas vezes. E alerta que, quanto mais tempo um gerador passa sem enviar código, maior o desvio acumulado possível: se ele ultrapassar o limite, a ressincronização automática não funciona, e é preciso autenticar o usuário por outro meio e ressincronizar explicitamente. É o caso de quem ativou o aplicativo há meses e só agora precisa dele.
Cada passo extra tem preço, e a RFC 4226 dá a fórmula
A tentação de alargar a janela para reduzir chamado de suporte tem custo mensurável. A RFC 4226 aproxima a segurança do HOTP por uma expressão em que a probabilidade de sucesso do adversário é o produto do tamanho da janela de sincronização pelo número de tentativas de verificação, dividido por dez elevado ao número de dígitos. Dobrar a janela dobra a chance de acerto de quem chuta, e aumentar as tentativas permitidas tem o mesmo efeito multiplicativo. Só os dígitos entram como expoente.
Por isso a mesma RFC recomenda um parâmetro de limitação de tentativas, com contadores individuais por dispositivo, ajustado tão baixo quanto possível sem prejudicar a usabilidade, e aponta uma alternativa em que o servidor espera um tempo crescente a cada falha. O ponto mais fácil de errar está na frase seguinte: o esquema de atraso ou bloqueio deve valer entre sessões de login, para impedir adivinhação paralela. Limitar tentativas por sessão não limita nada, como discutido em ataques de repetição e automação contra formulários.
O que o NIST exige de quem verifica
O NIST SP 800-63B classifica o gerador de senha de uso único como autenticador do tipo algo que você tem, e impõe requisitos que valem como checklist. A chave e o algoritmo devem oferecer pelo menos a força de segurança mínima da publicação SP 800-131A, que o documento registra como 112 bits na data de sua publicação. Quando o valor variável é baseado em relógio de tempo real, ele deve mudar pelo menos uma vez a cada dois minutos. O verificador deve aceitar um mesmo código apenas uma vez enquanto ele for válido, e pode avisar o usuário ao detectar tentativa de uso duplicado. Sobre a tolerância, o texto é normativo e genérico ao mesmo tempo: o tempo de vida do código deve ser determinado pelo desvio de relógio esperado do autenticador em qualquer direção ao longo de sua vida útil, mais uma margem para latência de rede e para o tempo de digitação. Há ainda a exigência de limitar tentativas falhas, obrigatória quando a saída tem menos de 64 bits, o que é o caso de qualquer código de seis dígitos.
Dois limites estruturais fecham o quadro. O primeiro: as chaves simétricas dos autenticadores estão também no verificador, e o documento manda protegê-las com controles que restrinjam a leitura aos componentes que precisam dela. Diferente de uma chave pública, esse segredo é roubável em lote. O segundo, e mais importante para quem desenha onboarding: a norma afirma que autenticação por senha de uso único não é resistente a phishing, porque a digitação manual não vincula o código à sessão em curso. Por isso o TOTP fica um degrau acima do SMS e um degrau abaixo da chave pública descrita em passkey e WebAuthn no cadastro, e serve bem a uma política de segundo fator como a discutida em MFA obrigatório sem trancar a equipe.
Perguntas frequentes
TOTP é mais seguro que o código por SMS?
Num aspecto específico, sim: ele não depende da rede telefônica, então não é afetado por troca fraudulenta de chip nem por desvio de mensagem na operadora. Nos demais é igual, porque continua sendo um código digitado, e o NIST classifica senha de uso único como não resistente a phishing.
O que acontece se o relógio do aparelho estiver errado?
O código corresponde a outro passo de tempo e é rejeitado, a menos que o desvio caiba na tolerância configurada. A RFC 6238 recomenda fixar um limite de passos nas duas direções, e avisa que desvio acumulado por longo tempo sem uso pode exceder esse limite, exigindo ressincronização com autenticação adicional.
Quantos dígitos o código precisa ter?
A RFC 4226 exige no mínimo seis e diz que sete ou mais devem ser considerados conforme o requisito de segurança. Na fórmula da própria norma, os dígitos entram como expoente na probabilidade de acerto por tentativa.
Fontes citadas
- RFC 6238, TOTP: Time-Based One-Time Password Algorithm, IETF, maio de 2011, seções 4, 5.2 (janela de validação) e 6 (ressincronização): rfc-editor.org
- RFC 4226, HOTP: An HMAC-Based One-Time Password Algorithm, IETF, dezembro de 2005, seções 4, 5.3, 7.1 (fórmula), 7.3 (tentativas) e 7.4 (sincronização): rfc-editor.org
- NIST SP 800-63B, Digital Identity Guidelines: Authentication and Lifecycle Management, seção 3.1.4: pages.nist.gov
