Os usuários da Internet têm que inserir senhas regularmente – por exemplo, ao entrar em plataformas de mídia social, fazer compras online ou usar internet banking. Senhas impedem que terceiros acessem dados confidenciais. No entanto, muitos usuários não são suficientemente diligentes em matéria de segurança online: os profissionais podem quebrar senhas simples em questão de segundos. Outras pessoas criam boas senhas, mas não conseguem armazená-las com segurança, *deixando assim uma porta aberta para criminosos. Além disso, as fraquezas nos serviços que os usuários assinam também não são pequenas. Se esses serviços não protegerem corretamente senhas, os dados de milhares de usuários podem estar em risco.

Uma maneira de minimizar o risco é usar autenticação de dois fatores ou autenticação multifatorial. Em vez de usar apenas uma senha, pelo menos um outro meio de autenticação é necessário. Os usuários desta tecnologia obtêm este fator de autenticação adicional através de seu smartphone ou um dispositivo de hardware especial (chamado de “token”). O ponto comum entre a maioria desses fatores adicionais é que eles são únicos e válidos apenas por um curto período de tempo – em outras palavras, uma senha única baseada no tempo é gerada. Vamos dar uma olhada em como isso funciona.

Conteúdo

  • Por que precisamos de um TOTP?
  • Como funciona o algoritmo de senha único baseado no tempo?
  • Exemplo de um cálculo TOTP

Por que precisamos de um TOTP?

Senhas convencionais – por mais fortes que o usuário as faça – têm uma desvantagem: se alguém conhece a cadeia de caracteres, a segurança não é mais garantida. Uma solução seria alterar senhas regularmente, mas mesmo os usuários mais exemplares não fazem isso a cada hora. A solução é um TOTP: uma senha que só é válida por um breve período, após o qual expira. A Força-Tarefa de Engenharia da Internet (IETF) publicou o algoritmo de senha única em 2011 na RFC 6238 para facilitar uma maior segurança on-line.

Senhas únicas são usadas principalmente como parte da autenticação de vários fatores, um sistema de segurança que exige que os usuários que entram em um serviço web primeiro digitem sua senha pessoal e estática e, em seguida, uma senha limitada de tempo gerada especialmente para esse login. O usuário recebe a segunda senha através de um aplicativo ou um token de hardware especial.

Uma vez que a senha única tenha sido usada ou se não tiver sido usada após um tempo especificado, ela expira. Portanto, é muito difícil para os criminosos obter o segundo fator, pois mesmo que eles saibam a senha estática, é muito difícil para eles obter o TOTP também, especialmente porque eles têm quase nenhum tempo para quebrá-lo.

Como funciona o algoritmo de senha único baseado no tempo?

O TOTP é baseado em uma função hash, que é um procedimento criptográfico pelo qual uma chave secreta e um carimbo de tempo são combinados para formar uma sequência de caracteres criptografadas. Tanto o usuário quanto o servidor conhecem a chave secreta. O carimbo de hora é dado no tempo do Unix.

Fato

O tempo unix é um valor correspondente ao número de segundos que se passaram desde 1º de janeiro de 1970.

TOTP é, na verdade, um desenvolvimento adicional do HOTP, que significa senha única baseada em HMAC. Como o HOTP, o TOTP é baseado no procedimento HMAC – a operação hash em segundo plano. Tanto o dispositivo do usuário quanto o servidor geram um valor de hash combinando a chave secreta com um contador. Os dois valores são idênticos, que é como a autenticação funciona.

A função hash em si não está definida; na prática, o SHA-1 é frequentemente usado (inclusive pelo Google Authenticator, por exemplo). O SHA-1 gera um valor de hash de 160 bits. Por conveniência, este valor é truncado usando uma função de compressão. O resultado final é um número curto (seis dígitos, por exemplo) que o usuário pode usar facilmente para fazer login no serviço web.

Nota

A chave secreta está incorporada em um token no dispositivo, o que significa que muitas vezes nem o usuário o conhece. Se este não for o caso, a chave secreta deve ser armazenada com segurança, idealmente offline, ou mesmo impressa e mantida em um lugar seguro, por exemplo. Se o usuário perder a chave secreta, ele não poderá mais fazer login no serviço.

Para a segunda parte da função, o HOTP usa um contador, e isso é compartilhado pelo servidor e pelo usuário. O problema com isso é que o código gerado permanece válido até que seja usado. TOTP restringe isso: o código gerado só pode ser usado dentro de um período de tempo definido. Como isso funciona?

Para o algoritmo de senha única baseado no tempo, existem três fórmulas importantes:

TOTP = HOTP (SecretKey,CurrentTime)

Esta fórmula básica simplesmente define que o TOTP é um procedimento HOTP com dois parâmetros – SecretKey e CurrentTime:

  • SecretKey: Senha gerada aleatoriamente, conhecida tanto pelo servidor quanto pelo cliente
  • CurrentTime: Tempo atual no tempo do Unix

No entanto, esse valor de tempo muda a cada segundo, o que não deixa o usuário tempo suficiente para digitar o código gerado. Ou seja, um segundo depois, o TOTP não é mais válido, pois o servidor já gerou um novo valor de hash. Portanto, é necessária uma outra fórmula:

CurrentTime = piso ((unixtime(agora) – unixtime(T0)/T1)

O parâmetro CurrentTime é definido da seguinte forma:

  • unixtime(agora): Tempo atual no tempo unix
  • unixtime(T0): Tempo de Unix em T0, o ponto a partir do qual os passos do tempo são contados – na maioria dos casos meia-noite em 1º de janeiro de 1970 (=0)
  • T1: O período para o qual o TOTP será válido (geralmente 30 segundos)
  • floor: Função de arredondamento para arredondar o valor calculado até um número inteiro

Nota

Em teoria, T0 pode ter qualquer valor, não necessariamente 0. O importante é que o cliente e o servidor selecionem o mesmo valor.

O efeito da divisão e arredondamento é que o resultado muda em intervalos definidos.

Em seguida, o valor de hash gerado é truncado para torná-lo mais fácil de usar.

Resultado = TOTPmod10d

A operação modulo gera um cheque:

  • mod 10: Modulo com divisor = 10
  • d: Número desejado de dígitos do TOTP

Em outras palavras, a base (10) é elevada ao número desejado de dígitos, então o TOTP é dividido por este valor e o restante é extraído.

Exemplo de um cálculo TOTP

Vamos supor que queremos gerar um TOTP que é válido por 30 segundos. Podemos começar calculando o CurrentTime e determinando por quanto tempo a validade será garantida. Para o unxtime(agora), vamos levá 1548322860, ou seja, 10:41 da manhã em 24 de janeiro de 2019. Se dividirmos esse valor em 30, teremos exatamente 51610762. Porque este já é um número inteiro, arredondamento daria o mesmo resultado. No entanto, se definirmos o CurrentTime 15 segundos depois (ou seja, 1548322875), após a divisão, o resultado é 51610762.5. Após arredondamento, o valor é 51610762, como antes. Portanto, o CurrentTime permanece o mesmo. A tabela a seguir mostra que um novo valor só é gerado a cada 30 segundos.

unixtime(now) unixtime(now)/30 floor(unixtime(now)/30)
1548322857 51610761.9000 51610761
1548322858 51610761.9333 51610761
1548322859 51610761.9667 51610761
1548322860 51610762.0000 51610762
1548322861 51610762.0333 51610762
1548322862 51610762.0667 51610762
1548322863 51610762.1000 51610762
1548322864 51610762.1333 51610762
1548322865 51610762.1667 51610762
1548322866 51610762.2000 51610762
1548322867 51610762.2333 51610762
1548322868 51610762.2667 51610762
1548322869 51610762.3000 51610762
1548322870 51610762.3333 51610762
1548322871 51610762.3667 51610762
1548322872 51610762.4000 51610762
1548322873 51610762.4333 51610762
1548322874 51610762.4667 51610762
1548322875 51610762.5000 51610762
1548322876 51610762.5333 51610762
1548322877 51610762.5667 51610762
1548322878 51610762.6000 51610762
1548322879 51610762.6333 51610762
1548322880 51610762.6667 51610762
1548322881 51610762.7000 51610762
1548322882 51610762.7333 51610762
1548322883 51610762.7667 51610762
1548322884 51610762.8000 51610762
1548322885 51610762.8333 51610762
1548322886 51610762.8667 51610762
1548322887 51610762.9000 51610762
1548322888 51610762.9333 51610762
1548322889 51610762.9667 51610762
1548322890 51610763.0000 51610763
1548322891 51610763.0333 51610763

Nosso CurrentTime é, portanto, estabelecido (51610762). Agora usamos um gerador de senhas para obter o SecretKey: >cHSB_UQ#O5m;~b

HMAC (com SHA-1) combina a chave secreta e o tempo atual para produzir um valor de hash (em formato hexadecimal): c0 62 37 94 dd 37 7a 3a f0 91 22 08 1f 21 6f 9b 17 4b 17 45. Este valor de 160 bits (20 byte) é truncado a 31 bits usando o que é conhecido como truncação dinâmica. Isso envolve a realização das seguintes etapas: Primeiro, os últimos 4 bits são considerados. Em nosso exemplo, este é o número 0x5, que também pode ser escrito como 5 em notação decimal. Isso dá o valor de deslocamento a ser usado para truncação dinâmica, e significa que a partir do byte com o índice 5, devemos extrair quatro bytes (leia-se da esquerda, a partir de 0): 0x377a3af0. Neste exemplo nosso valor já começa com um pouco igual a 0. Se este não for o caso, deve ser alterado em conformidade. O valor de 31 bits aqui é assim: 0x377a3af0, ou 930757360.

Para reduzir esta sequência de 9 dígitos para 6 dígitos, usamos uma operação de modulo, enchimento do resultado com zeros principais, se necessário: 930757360 mod (106) = 757360. Este é agora o TOTP, que é válido por 30 segundos. Em combinação com outro fator, isso torna o procedimento de login bastante seguro.


Artigo Original