Article image
Lucas Palhano
Lucas Palhano29/03/2023 10:12
Compartilhe

Suas senhas são (muito provavelmente) ruins — Parte 1

  • #Segurança da informação

Senhas. Todos os dias, em algum momento, temos que lidar com elas. Seja para acessar nossas contas bancárias, redes sociais, e-mails ou mesmo um jogo para passar o tempo, elas estão sempre lá, no meio do caminho. E parece que elas nunca são boas o bastante: a senha é muito curta, muito longa, não tem caracteres especiais suficientes, é fácil demais de adivinhar, é difícil demais para lembrar… É como se as senhas existissem apenas para dificultar as nossas vidas.

Mas por que será que elas são tão importantes? Por que nunca adicionamos caracteres o suficiente? E o que podemos fazer para tornar nossas senhas mais eficazes? Bem, eu espero conseguir esclarecer um pouco disso tudo ao longo deste artigo, que será dividido em duas partes.

Nesta primeira parte pretendo tratar sobre o que são senhas, e o que às torna seguras ou inseguras. Já na segunda parte, eu irei abordar as formas de gerar senhas seguras, e também de armazená-las apropriadamente. No fim, caso tudo dê certo, acredito que você entenderá o porque de suas senhas serem (muito provavelmente) ruins.

O que é uma senha?

A principio, uma senha nada mais é que uma forma de autenticação, ou seja, de provar que você é você mesmo. Na verdade, a senha é apenas uma das diversas formas de autenticação existentes. No geral, existem três grupos de autenticação, a saber: (1) o que você sabe, (2) o que você tem e (3) o que você é.

Entre as autenticações referentes ao “que você sabe” nos temos a própria senha, mas também os tokens de autenticação. Já no grupo do “que você tem”, por exemplo, nós temos o celular (com um chip ou um aplicativo de autenticação), ou mesmo um cartão. Por fim, o “que você é” diz respeito em grande parte à biometria, como dados de digital, íris, voz ou face.

Ainda, é possível que determinados sistemas implementem mais de um modal de autenticação, como por exemplo os cartões de crédito, que são cartões físicos únicos (o que você tem), mas que dependem de uma senha para serem utilizados (o que você sabe). Em outros casos, sistemas online podem exigir um duplo fator de autenticação, mais conhecida como “Autenticação em dois fatores” ou 2FA. Neste caso, nós tipicamente teremos a tradicional senha (o que você sabe) associada à um código vinculado ao seu dispositivo móvel (o que você tem), sendo estes justamente os dois fatores.

O problema das senhas

No geral, as senhas são o modo de autenticação mais difundido disparado, e há um motivo para isso. Elas são fáceis de implementar, são muito escaláveis e também bastante simples de usar (ao menos, em teoria). Assim, tornam-se uma opção padrão para a maioria dos sistemas online.

É importante lembrar, contudo, que nem todos os sistemas precisam de senha. Sistemas que não fazem distinção entre usuário, como uma landing-page ou um site de notícias estático, não precisa de autenticação, uma vez que ele irá exibir os mesmos dados independentemente de quem o esteja acessando.

Assim, via de regras esses mecanismos de autenticação são necessários justamente quando estamos lidando com informações privadas, cujo conhecimento por terceiros pode trazer prejuízos para o seu detentor. Pense por exemplo em um site de banco online: Ele precisa saber quem tem quanto em que conta. Caso ele não consiga autenticar os usuários, torna-se simplesmente inviável permitir a exibição e manipulação de cada saldo por cada um dos clientes de forma individualizada.

Contudo, o que acontece caso um terceiro tenha acesso às suas senhas deste serviço de internet banking? Bem, para todos os casos, este terceiro será tratado como sendo você, ao menos pela plataforma. Isso trás sérias implicações, pois qualquer um que consiga se autenticar como você, será necessariamente você, e terá acesso a todos os dados e funcionalidades que supostamente deveriam estar restritas única e exclusivamente a você.

Este é o problema das senhas: Elas provam que você é você, e qualquer um que saiba sua senha, pode provar que é você. Assim, no final das contas, tudo que separa a internet de uma completa anarquia são as senhas, um simples grupo de caracteres tão mal tratado por nós usuários.

Quão boa é uma senha?

Talvez eu tenha conseguido lhe convencer que é importante ter uma boa senha (e não compartilhá-la com ninguém que não seja você mesmo). Mas então, como saber se minha senha atual é boa? E por que ela muito provavelmente não é?

Primeiramente, é importante ressaltar que existem dezenas de fatores a se levar em conta quando queremos considerar se uma senha é ou não boa, mas no momento iremos nos ater a apenas alguns mais relevantes: a força da senha.

A força da senha é medida através de um cálculo que verifica o número de tentativas necessárias para conseguir a adivinhar através do método de força bruta. Este método de força bruta, por sua vez, nada mais é do que o teste consecutivo de todas as combinações possíveis de caracteres, das mais simples às mais complexas.

Um exemplo bastante simples é uma senha numérica de 4 dígitos. Sabendo que ela pode variar entre 0000 e 9999, nós iremos simplesmente tentar cada combinação possível até encontrar a senha. Ou seja, tentaremos 0000, 0001, 0002… 9996, 9997, 9998 até o 9999. Nesta situação, é certo que a senha desejada estará contida dentro deste grupo testado.

Número de tentativas

O cálculo do numero de tentativas necessárias (P) para quebrar uma senha pode ser descrito então como simplesmente o tamanho do conjunto de símbolos (S) elevado ao número de caracteres (n), ou P = S ^ n.

Mas o que isso significa a final? Simples: se eu tenho uma senha “senha123”, então o tamanho do meu conjunto de símbolos será 36, pois temos letras minúsculas (26) e dígitos numéricos (10), tal como uma senha de 8 caracteres, o que nos leva ao cálculo de 36 ^ 8 = 2.821.109.907.456.

Caramba, são necessárias 2 trilhões de tentativas para quebrar essa senha, então ela é segura, certo? Bem, se o hacker fosse tentar descobrir a senha na força bruta usando um caderno e uma caneta, eu diria que você poderia ficar tranquilo, mas a verdade é que ele vai usar um computador, e muito provavelmente esse computador vai ter pelo menos uma placa de vídeo, o que torna o trabalho bem menos cansativo.

Tempo necessário

Para se ter uma noção do tempo necessário (T) para quebrar uma senha desta, nós só precisamos dividir o número de tentativas necessárias (P) pela quantidade de tentativas por segundo (t) que uma determinada máquina pode executar, ou T = P / t.

Aqui, para que consigamos calcular nós precisaremos realizar uma estimativa do número de tentativas por segundo que um possível atacante consiga operar. É importante considerar que esta estimativa pode variar entre algumas centenas de milhares até alguns trilhões. Tal discrepância se dá muito em função de fatores tais como o hardware utilizado, assim como a qualidade do algoritmo e mesmo a linguagem em que este foi programado.

Para todos os efeitos, vamos considerar inicialmente que nosso suposto atacante consegue operar 30 milhões de tentativas usando uma placa de vídeo razoável. Neste caso, teremos que nossa querida senha deverá ser quebrada em aproximadamente 94037 segundos, mais conhecido como 26 horas.

Não parece tão ruim? Bem, eu irei deixar uma tabela logo abaixo com as relações entre as senhas mais comuns (que eu espero que você não use) e seus respectivos tempos de quebra, dados os valores considerados até então:

image

Muito pior do que parece…

Os dados apresentados anteriormente podem parecer promissores, afinal a pass@123 tem apenas 8 caracteres e nem conta com maiúsculas, mas mesmo assim levaria metade de um ano para ser quebrada. Mas isso é uma ilusão, a verdade é que a estimativa de 30 milhões de tentativas por segundo é simplesmente muito pequena, pois é alcançável por computadores convencionais, enquanto os hackers minimamente competentes investem em equipamentos bastante elaborados, capazes de operar muito mais cálculos por segundo.

Ainda, vale lembrar que a cada ano o poder computacional aumenta de forma considerável, o que significa que a cada momento nossas senhas estão ficando mais e mais fracas.

Considerando uma situação em que o atacante consiga executar 10 bilhões de operações por segundo, nós chegamos a conclusão de que a senha pass@123 pode ser quebrada em apenas 14 horas, e não mais em 128 dias, tal como anteriormente.

Caracteres e tamanho

Parando para refletir sobre o que acabamos de analisar, nós conseguimos alcançar uns insights interessantes. Um deles é o de que se caso a sua senha seja composta apenas por números, ela é simplesmente inútil. Sim, ela pode ate ser grande (pelo menos mais de 15 dígitos), mas sinceramente, seria melhor uma senha menor com outros caracteres que essa senha grande composta apenas por números.

Outro ponto é que, ao analisar a composição do total de tentativas necessárias para quebrar a senha, nós finalmente entendemos o motivo de implicarem tanto com caracteres especiais e com o tamanho da senha. A questão é que são justamente o conjunto de possíveis caracteres e o tamanho da senha que compõem a complexidade de quebrar a senha. Uma senha grande com caracteres pouco variados (como apenas números ou letras) será inefetiva, e o mesmo vale para uma senha com muitos caracteres distintos, porém, pequena.

Os caracteres especiais são particularmente importantes pois são o conjunto com o maior número de caracteres, sendo 33 segundo a tabela ASCII. Isso significa que estes são os que mais fazem volume na base da exponenciação, gerando assim um número bastante elevado de tentativas necessárias para quebrar uma senha que faça uso destes.

A seguir, eu exibo uma tabela que destaca a quantidade de combinações possíveis entre os diferentes tipos de caracteres disponíveis (numérico, minúsculo, maiúsculo e especial), e determina o tempo necessário para sua quebra de acordo com diferentes tamanhos de senha.

image

Vale ressaltar que neste exemplo eu busquei ser um pouco mais realista e lidar com um atacante operando 1 bilhão de operações por segundo. Essa é uma boa estimativa para considerar hackers que não sejam civis comuns. Vê como neste caso, mesmo uma senha numérica com 16 dígitos ainda é extremamente fraca? E evidentemente, o mesmo vale para senhas com menos de 12 caracteres.

Olhando os resultados das senhas de 16 caracteres você pode pensar que talvez essa quantidade seja o suficiente, e talvez seja mesmo, mas seguro morreu de velho. Pense da seguinte forma: Se eu já cheguei nos 16 caracteres, por que parar aqui? Por que não chegar nas duas dezenas? Bem, pelo menos é assim que eu penso.

Calculador de tempo

Como eu gosto mesmo é de programar, não poderia deixar de mostrar alguns códigos voltados para esse tema de força das senhas. Aqui eu tenho um script para verificar o tempo estimado para a quebra de uma determinada senha inserida pelo usuário. A parte legal é que manipulando a variável testes_segundo você consegue obter resultados diferentes, pois é ela quem determina o poder computacional do atacante.

import string

def calcular_tempo_quebrar(senha_testada):
  simbolos = qtd_caracteres_possiveis(senha_testada)
  testes_segundo = 1e9
  tentativas = simbolos ** len(senha_testada)
  tempo = tentativas / testes_segundo
  return round(tempo)


def qtd_caracteres_possiveis(senha_testada):
  decimal = any(letra in string.digits for letra in senha_testada)
  lowercase = any(letra in string.ascii_lowercase for letra in senha_testada)
  uppercase = any(letra in string.ascii_uppercase for letra in senha_testada)
  symbols = any(letra in string.punctuation for letra in senha_testada)

  lista_dicionarios = [string.digits, string.ascii_lowercase, string.ascii_uppercase, string.punctuation]
  lista_ocorrencia = [decimal, lowercase, uppercase, symbols]
  qtd_simbolos = [len(lista_dicionarios[i]) for i in range(len(lista_dicionarios)) if lista_ocorrencia[i]]
  simbolos = sum(qtd_simbolos)

  return simbolos


def formatar_tempo(segundos):
  minutos = segundos // 60
  segundos = segundos % minutos if minutos else segundos
  horas = minutos // 60
  minutos = minutos % horas if horas else minutos
  dias = horas // 24
  horas = horas % dias if dias else horas
  anos = dias // 365
  dias = dias % anos if anos else dias
  return {
      "Anos": anos,
      "Dias": dias,
      "Horas": horas,
      "Minutos": minutos,
      "Segundos": segundos
  }


if __name__ == "__main__":
  senha = input("Insira a senha a ser avaliada: ")
  segundos_quebrar = calcular_tempo_quebrar(senha)
  tempo_anos = formatar_tempo(segundos_quebrar)
  print("\nTempo necessário para quebrar a senha:")
  [print(f"{key}: {value}") for key, value in tempo_anos.items()]

O funcionamento do script é bem simples, e a ideia em essência é receber uma senha e verificar quais tipos de caracteres ela possui. Após isso, basta executar a operação levando em consideração o conjunto de caracteres dentro da variável simbolos, o tamanho da senha e a quantidade de testes por segundo (que foi configurada manualmente como 1 bilhão, mas que pode ser modificada).

Conclusão

Agora eu espero que você realmente tenha entendido o motivo de se preocupar com o tamanho e os caracteres de sua senha. Melhor ainda, acredito que você consiga avaliar por conta própria a força de suas senhas!

Contudo, ainda temos muito o que falar sobre senhas: desde outras formas de ataque além da força bruta, até formas de gerar senhas realmente seguras e armazená-las de forma confiável.

Mas isso tudo é assunto para um próximo artigo. Até lá!

OBS: Caso você não queira calcular a força de suas senhas manualmente ou executando um script Python pelo terminal, existem diversos sites em que você pode avaliar a força e a qualidade de suas senhas, como: Kaspersky, Security, e o testedesenha (recomendado para ver outros fatores de qualidade numa senha).

Compartilhe
Comentários (4)
Denilson Palma
Denilson Palma - 29/03/2023 18:37

Obrigado por este artigo! Parabéns! Esta ótimo!

Lucas Palhano
Lucas Palhano - 29/03/2023 14:37

Valeu Eric, eu gosto muito desses assuntos que não são tão abordados mas que são bem importantes para o ambiente digital. Algoritmos, estruturas de dados, arquitetura de computador, criptografia, segurança de senhas... Espero estar cada vez mais compartilhando conhecimento sobre essas coisas por aqui.

Sim, Pablo. Realmente, os serão um grande desafio para as senhas, e até para a criptografia que também protege nossa privacidade no mundo virtual. Uma coisa interessante é que atualmente já estão sendo desenvolvidos algoritmos de criptografia quântica, o que provavelmente vai mitigar as vulnerabilidades que a computação quântica vai trazer para a criptografia normal. Contudo, isso não resolve a parte das senhas... Já pensou se no futuro nós tivermos que gerar senhas de mais de 100 caracteres para evitar que computadores quânticos consigam quebrá-las?

Pablo Holanda
Pablo Holanda - 29/03/2023 12:37

Muito bom. Com os computadores quânticos, essa tarefa torna-se cada vez mais fácil.

EM

Eric Morais - 29/03/2023 10:29

Ótimo conteúdo.