Por que os códigos TOTP falham quando o relógio do dispositivo se desvia
O código é um hash do segredo e do passo de tempo atual. Compare os desvios nas duas pontas e depois corrija o relógio em vez de ampliar a janela.
Códigos de uso único podem estar perfeitamente corretos no seu telefone e ainda assim serem rejeitados pelo servidor no mesmo segundo. Os dois lados calculam a mesma função a partir de um segredo compartilhado e do passo de tempo atual, então uma discordância sobre o horário produz uma discordância sobre o código. Isso transforma o desvio do relógio em uma falha relevante para a segurança, e não apenas em um incômodo.
Dois relógios importam aqui, e corrigir o visível é a parte que as pessoas fazem primeiro. O que costuma precisar de atenção é o outro.
O código é uma função do tempo, não uma senha
O TOTP usa o segredo compartilhado e um contador derivado do horário atual, passa os dois por um hash com chave e trunca o resultado em uma cadeia decimal curta, conforme especificado na RFC 6238. O contador avança a cada passo de tempo, convencionalmente trinta segundos, então o mesmo segredo produz um valor novo quando o passo muda. O verificador recalcula o valor esperado para o passo atual e compara, o que exige o mesmo segredo e a mesma ideia de agora. Uma senha continua reutilizável até ser trocada, enquanto esse valor expira em um limite que o cliente não consegue ver.
É por isso que um código funciona e o seguinte falha instantes depois. Isso também explica por que copiar um código de uma mensagem de chat é um hábito tão pouco confiável.
Dois relógios precisam concordar, não um
O material de registro é a primeira coisa compartilhada, e o tempo é a segunda. Se o segredo está correto enquanto os relógios diferem mais que a janela tolerada, cada valor gerado cai no passo errado e é rejeitado. Se os relógios concordam enquanto o segredo está errado, cada valor também é rejeitado, e as duas falhas parecem idênticas na tela de login. Separá-las significa verificar o registro da conta e o tempo de forma independente, nessa ordem.
O relógio do verificador merece a mesma análise que o do dispositivo. Um servidor cuja fonte de tempo está quebrada rejeita códigos corretos de todos os usuários de uma vez, e os relatos descreverão uma interrupção súbita em vez de um desvio. Vale reconhecer esse padrão, porque a correção pertence ao servidor e não a cem telefones.
O que custa ampliar a janela
As implementações podem aceitar um código de um passo adjacente para absorver diferenças pequenas, e essa tolerância é uma decisão de projeto, não um ajuste gratuito. Cada passo extra multiplica o número de valores válidos em qualquer momento, que é exatamente o que prefere um atacante que adivinha. A regra de repetição importa pelo mesmo motivo, já que um código aceito duas vezes é um código que vazou de forma útil. Um administrador que amplia a janela para silenciar reclamações troca uma propriedade real por uma melhoria cosmética.
Corrigir o relógio é o reparo, enquanto ampliar a janela é um sedativo. O primeiro remove a causa e o segundo a esconde.
Verifique os dois relógios antes de tentar novamente
Leia o horário no dispositivo e no servidor, e compare os desvios em vez dos horários locais exibidos. Os comandos abaixo mostram o estado de sincronização e o instante UTC bruto em um host ou servidor Linux. Execute-os nas duas pontas antes de alterar qualquer configuração de autenticação.
timedatectl
date -u +'%Y-%m-%dT%H:%M:%SZ'
chronyc tracking
timedatectl timesync-status
Um desvio medido em segundos é inofensivo, um medido em minutos explica uma rejeição, e um sistema que não relata nenhuma fonte de sincronização é candidato a ambos. Compare os dois carimbos de tempo UTC diretamente, já que o horário local inclui um fuso horário que o algoritmo nunca vê. Se os desvios são pequenos e os códigos ainda falham, pare de ajustar relógios e examine o registro de inscrição. Tentativas repetidas contra uma conta bloqueada tornam a falha original mais difícil de observar.
Registre o horário da rejeição, o desvio e o texto do erro, e deixe o segredo compartilhado fora disso. O suporte consegue trabalhar com os três primeiros e nunca deveria ver o quarto.