O guia completo do TOTP em equipa

Como funciona o TOTP, que propriedades do algoritmo causam todos os problemas das contas partilhadas, e o que uma equipa tem de montar.

O TOTP recebe duas entradas e produz uma saída. As entradas são um segredo partilhado e a hora atual; a saída é um código de seis dígitos que qualquer pessoa que detenha o mesmo segredo consegue calcular. Não há qualquer chamada de rede, qualquer registo por aparelho, nem qualquer rasto do lado do servidor do aparelho que produziu um código.

Todas as dificuldades que uma equipa encontra com a 2FA em contas partilhadas decorrem desta frase. Este guia explica o mecanismo, e depois o que ele implica para uma equipa de mais de uma pessoa.

O que é o TOTP?

O TOTP está especificado na RFC 6238. É uma camada fina por cima do HOTP (RFC 4226), que produz um código a partir de um segredo e de um contador. O HOTP incrementa o contador a cada uso; o TOTP substitui o contador pela hora atual dividida em passos fixos, para que os dois lados cheguem ao mesmo valor sem comunicar.

Como funciona o TOTP?

Uma geração é parecida com isto:

counter = floor(unix_time / period)        # o período é em geral de 30 segundos
digest  = hmac_sha1(secret, counter)       # 20 bytes
offset  = digest[-1] & 0x0F                # truncagem dinâmica
number  = int_from(digest[offset:offset+4]) & 0x7FFFFFFF
code    = number % 10 ** digits            # preenchido com zeros, 6 dígitos em geral

Quatro parâmetros estão em jogo: o segredo, o período (30 segundos por omissão), o número de dígitos (6) e o algoritmo (SHA-1 na prática). A aplicação de autenticação de um telemóvel faz exatamente o acima, offline. O servidor faz o mesmo e compara.

Duas consequências merecem ser ditas com clareza, porque é aí que começam a maior parte dos mal-entendidos:

  • Nada num código identifica a sua origem. O servidor vê seis dígitos que correspondem, não que aparelho ou que pessoa os produziu.
  • Não há qualquer estado a revogar. Inscrever um aparelho não é um registo, é uma cópia do segredo. Nada na conta guarda rasto disso.

O segredo é a conta

O segredo tem em geral 16 a 32 carateres base32. Não expira, não está ligado a nenhum aparelho, e o protocolo não tem qualquer noção da sua rotação.

Quando lê um código QR de configuração, está a ler um URI no formato publicado com o nome de Key URI Format:

otpauth://totp/Acme:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=Acme&algorithm=SHA1&digits=6&period=30

Esta cadeia é a credencial inteira. O código QR é uma fotografia dela. O que quer dizer que uma captura do ecrã de inscrição não é uma comodidade. É o segundo fator, sob uma forma que se reencaminha, se guarda em cópia e se indexa.

Daí decorrem as propriedades que tornam incómoda a 2FA partilhada:

  1. A posse vale acesso permanente. Quem tem o segredo pode produzir todos os códigos futuros, em qualquer aparelho, para sempre.
  2. As cópias são invisíveis. Nenhuma página de segurança lhe dirá alguma vez quantas existem.
  3. Revogar quer dizer retomar tudo. A única forma de invalidar uma cópia é desativar a 2FA na conta e voltar a configurá-la, para toda a gente.

A inscrição, passo a passo

O que acontece durante a configuração explica porque algumas escolhas posteriores são irreversíveis.

  1. O fornecedor produz o segredo. É criado do lado do servidor, registado na sua conta, e não volta a mudar a menos que a 2FA seja desativada.
  2. É apresentado uma vez, sob a forma de código QR e em geral sob a forma de cadeia base32 atrás de uma ligação «não consegue ler?». É o único momento em que a credencial é mostrada a um humano.
  3. O seu cliente guarda-o. Uma aplicação de autenticação escreve-o no aparelho; um cofre de equipa escreve-o no seu próprio armazenamento cifrado. Os dois fazem o mesmo: guardar uma cópia.
  4. Submete um código para confirmar. Isso prova que a cópia funciona. Não é um registo do aparelho: nada a respeito do seu telemóvel é enviado para lado nenhum.
  5. O fornecedor entrega códigos de recuperação, em geral nesse momento, e em geral uma só vez.

O passo 2 é toda a aposta. O que vir esse ecrã detém o segundo fator da conta a partir daí, e o passo 4 não dá qualquer indicação sobre quantas coisas o viram. É por isso que «vamos só tirar uma captura por agora» é uma decisão sem data de validade, e é por isso que a boa pergunta durante a configuração não é quem o lê, mas onde vai viver a única cópia.

Porque existe a janela de trinta segundos

Os dois lados têm de se entender sobre o contador sem falar um com o outro: entendem-se, portanto, sobre a hora. Um passo de trinta segundos é o compromisso: suficientemente longo para escrever um código, suficientemente curto para que um código capturado não valha mais nada pouco depois.

Os verificadores aceitam em geral também o passo imediatamente anterior, e por vezes o seguinte, para absorver o tempo de escrita e os pequenos desvios de relógio. É por isso que um código muitas vezes ainda funciona alguns segundos depois de a contagem decrescente voltar a zero.

Quer também dizer que os relógios contam. Um aparelho cujo relógio tenha um minuto de desvio calcula os códigos de um passo que o servidor já deixou, e todos os códigos são rejeitados. Quando alguém diz que os códigos deixaram de funcionar, um relógio não sincronizado é a primeira coisa a verificar, antes de supor que o segredo está errado. Tudo o que produz códigos para uma equipa precisa de um relógio sincronizado como exigência estrita, não como conforto.

Como funciona a verificação, e porque um código só devia servir uma vez

Do outro lado, o verificador calcula o código esperado para o passo atual e compara. Três pormenores desta comparação contam para quem gere contas partilhadas.

A janela de aceitação é um compromisso deliberado. Cada passo suplementar aceite por um servidor prolonga o tempo durante o qual um código capturado continua utilizável. Um passo para trás é normal; janelas largas assinalam um serviço que disfarça problemas de relógio.

Um código devia ser de uso único. A RFC 6238 diz explicitamente que uma segunda autenticação com o mesmo passo de tempo devia ser recusada, e as boas implementações seguem o último passo usado por conta. O efeito prático para uma equipa: duas pessoas que entram nos mesmos trinta segundos podem ver a segunda tentativa rejeitada mesmo que o código mostrado esteja correto. Esperar pelo código seguinte é o remédio, e não é um erro.

As tentativas deviam ser limitadas. Seis dígitos são um milhão de possibilidades, o que só resiste à força bruta se o servidor limitar as tentativas. Essa proteção vive inteiramente do lado do fornecedor; nada do que fizer com o segredo a melhora.

Nenhum destes pontos se configura do lado de uma equipa, mas os três explicam sintomas que, de outro modo, parecem uma configuração avariada: um código que funciona com atraso, um código que funciona para um colega e não para o seguinte, um início de sessão que começa a recusar códigos corretos depois de uma rajada de tentativas.

O TOTP é seguro? Contra o que protege e contra o que não protege

Defende bem contra as palavras-passe reutilizadas, o credential stuffing oriundo de fugas, e uma palavra-passe fugida isoladamente. Um atacante que só tem a palavra-passe não consegue entrar.

Não defende contra uma retransmissão em tempo real: uma página de início de sessão falsa convincente que pede o código e o transmite dentro da sua janela de validade. Os códigos TOTP são suscetíveis de phishing por conceção, já que o utilizador os pode ler. Também não faz nada contra software malicioso no aparelho que os produz, um cookie de sessão roubado, ou um segredo copiado.

Este último ponto é a falha que diz respeito às equipas. Todas as outras ameaças da lista são tratadas pelas definições de segurança da própria conta. Um segredo copiado só é tratado pela forma como a sua equipa o guarda, coisa que o fornecedor não consegue ver nem ajudar.

Onde as equipas quebram o TOTP

Por dano crescente:

  • Uma pessoa fica com a aplicação. Nenhum segredo é copiado, mas a conta passa a depender da disponibilidade de um ser humano.
  • Um telemóvel dedicado numa gaveta. Ótimo no escritório, inútil à distância, e não regista nada.
  • O segredo ao lado da palavra-passe num cofre partilhado. Prático, e junta os dois fatores num só recipiente.
  • O código QR publicado num canal. Distribuição permanente e incontável da credencial.

Os compromissos de cada um, e a forma de escolher, são o assunto das melhores formas de gerir a 2FA de uma conta partilhada e, tipo de conta a tipo de conta, de a 2FA de uma conta partilhada: como deve uma equipa lidar com ela?.

O que exige uma instalação TOTP à medida de uma equipa

Uma instalação que sobrevive a mais de uma pessoa precisa de seis coisas, seja qual for a ferramenta escolhida. É a lista a verificar antes de escolher.

Uma guarda única do segredo. Um só sítio o detém, introduzido uma vez, pela pessoa que administra a conta. Todo o resto consome códigos.

Uma distribuição dos códigos sem distribuição do segredo. Quem tem de entrar obtém o código atual e a contagem decrescente, e não consegue reconstituir o segredo a partir do que vê.

Uma autorização por pessoa e por conta. Não por cofre. Quem publica no perfil social não tem razão nenhuma para produzir códigos para o prestador de pagamentos.

Um rasto das consultas de códigos. O registo do fornecedor mostrará a conta partilhada, não a pessoa. Um registo de quem pediu um código é a única coisa que reduz um incidente a um nome e a uma marca temporal.

Um relógio sincronizado em todo o lado onde se produzem códigos, pela razão dada acima.

Um caminho de recuperação testado. É a parte que as equipas descobrem no pior momento.

Cópias de segurança e recuperação

Duas coisas distintas têm de ser recuperáveis, e não deviam viver nem no mesmo sítio uma da outra, nem na conta que protegem.

O segredo, porque perdê-lo obriga a repor a 2FA da conta. A sua localização devia estar anotada, e ser alcançável por mais do que um administrador.

Os códigos de recuperação do fornecedor, que são recursos de uso único entregues na inscrição. Servem para o dia em que o segredo desapareceu, não para o acesso diário: são em número finito, e ninguém consegue dizer qual foi gasto por quem.

Guardar a única cópia de um código de recuperação na conta que ele recupera é um circuito que se fecha exatamente quando precisa dele aberto. O mesmo para o segredo da conta que guarda o cofre que contém os seus segredos.

O caminho de recuperação merece ser percorrido uma vez, de propósito, numa conta sem importância: desativar a 2FA com um código de recuperação, voltar a configurá-la, verificar que todos os que precisam dos códigos os continuam a ter. Sem esse ensaio, vai descobrir o procedimento no dia em que a conta já está inacessível.

Os parâmetros que vai mesmo encontrar

Os valores por omissão cobrem a esmagadora maioria: SHA-1, seis dígitos, trinta segundos. O uso do SHA-1 aqui não é a fraqueza que parece, uma vez que o HMAC-SHA1 não é afetado pelos ataques por colisão que reformaram o SHA-1 para as assinaturas. A RFC autoriza SHA-256 e SHA-512, mas o suporte por parte das aplicações é suficientemente desigual para que os fornecedores raramente os usem.

Uma minoria de serviços afasta-se: oito dígitos, um período de sessenta segundos, ou um alfabeto de código não numérico. A consequência prática é uma exigência de armazenamento. O que detém um segredo tem de deter os seus parâmetros digits, period e algorithm ao lado, sem o que os códigos dessas contas estarão errados de uma maneira que parece um segredo avariado. Qualquer ferramenta que só aceite uma cadeia de segredo nua presume em silêncio os valores por omissão.

Pequeno glossário

Vale a pena entender-se sobre isto dentro de uma equipa, porque estas palavras são usadas indiferentemente e as pessoas acabam a falar de coisas diferentes.

  • Segredo (ou semente): a cadeia base32 de onde vêm os códigos. Permanente.
  • Chave: na maioria das vezes um sinónimo de segredo. Por vezes designa-se assim o Key URI, que é outra coisa.
  • Código (ou OTP): os seis dígitos. Válido um passo, de uso único.
  • Token: usado indiferentemente para os seis dígitos e, num aparelho dedicado, para o aparelho que detém o segredo. Precisar qual.
  • HOTP: a mesma construção com um contador que se incrementa a cada uso.
  • Período / passo de tempo: o intervalo de validade de um código, em geral 30 segundos.
  • Deriva: o desvio entre dois relógios, que faz os códigos falharem.
  • Key URI / URI otpauth: a forma textual da carga de inscrição; o código QR é a sua codificação visual.
  • Códigos de recuperação: recursos de uso único fornecidos pelo serviço, sem relação com o TOTP.
  • Inscrição: a cópia do segredo para um aparelho. Não um registo, apesar da impressão que dá.

Onde se coloca a Share Auth

A Share Auth põe em prática as seis exigências acima para as contas que têm mesmo um só identificador. Os segredos são introduzidos uma vez e cifrados em repouso, com digits, period e algorithm guardados ao lado; os membros veem códigos e contagens decrescentes em vez de segredos; as permissões são por membro; e cada consulta é escrita num registo de acessos. Retirar um membro retira-lhe o acesso a todas as contas de uma vez.

Não é um substituto do acesso por pessoa nas plataformas que o propõem. Onde uma ferramenta puder dar a cada colega o seu próprio identificador e o seu próprio segundo fator, isso é estritamente melhor do que partilhar seja o que for.

Lista de verificação

  • O segredo de cada conta partilhada tem uma casa conhecida, alcançável por dois administradores.
  • Ninguém precisa do segredo para obter um código.
  • O acesso é concedido por pessoa, por conta, e retirável numa ação.
  • As consultas de códigos são registadas no momento em que acontecem.
  • Os códigos de recuperação estão arrumados com o segredo, fora da conta que eles recuperam.
  • Os relógios estão sincronizados em todo o lado onde se produzem códigos.
  • O caminho de recuperação foi testado uma vez, de propósito.
  • Qualquer conta cujo código QR tenha sido partilhado um dia teve a sua 2FA reposta.

Perguntas frequentes

TOTP, de «time-based one-time password», é o algoritmo especificado pela RFC 6238 que transforma um segredo partilhado e a hora atual num código curto, seis dígitos na maioria dos casos, válido uns trinta segundos. A conta e a aplicação de autenticação detêm o mesmo segredo: calculam, portanto, o mesmo código sem trocar nada.

Leia também · Como funciona o TOTP