Quantas vezes você se cadastrou em um site e pensou ai gente por que a senha tem que ser tão grande? Vamos entender a real necessidade de ter uma senha considerada “forte” e para isso vamos aprender primeiro como gerar uma senha forte com Python, para isso vamos aprender um novo conceito: número randômico.
Uma sequência randômica corresponde a uma sequência de números que não pode ser prevista, cada seguinte algarismo não tem relação nenhuma com o anterior. As linguagens de programação possuem geradores pseudo randômicos, por que para gerar estes números eles possuem uma fórmula interna, e essa fórmula recebe uma semente. Se você passar a mesma semente para a fórmula a sequência de números gerada sempre será igual. É possível configurar a semente chamando a função seed(). Se você passar a mesma semente a sequência de números será igual sempre.
Função random em Python
Veja o exemplo da utilização da função random com um seed definido.
from random import seed, random
seed(1)
print(random()) #0.134364244112
print(random()) #0.847433736937
seed(1)
print(random()) #0.134364244112
print(random()) #0.847433736937
O que as linguagens de programação fazem para gerar números randômicos é gerar uma semente diferente a cada vez que você chama a função. No Python essa semente é um número que representa a quantidade de milissegundos que se passaram desde 1 de janeiro de 1970. Por tanto toda vez que você utiliza a função random sem setar uma semente, um número diferente é gerado.
from random import seed, random
print(random()) # 0.885350193339
print(random()) # 0.381136740351
print(random()) # 0.634755066626
print(random()) # 0.130661237179
Gerar uma senha randômica
Vamos usar a função choice() do módulo random. A palavra choice significa escolha em inglês, é justamente isto que a função faz: escolhe um item de uma list de itens aleatóreamente. Vamos criar uma lista com todos os caracteres que queremos utilizar para gerar nossa senha. Poderíamos criar uma string com todos os caracteres que queremos incluir por exemplo “abcdef..” mas não é necessário pois o Python tem essa funcionalidade embutida. O módulo string tem várias propriedades que nos ajudam.
import string
string.ascii_lowercase # abcdefghijklmnopqrstuvwxyz
string.ascii_uppercase # ABCDEFGHIJKLMNOPQRSTUVWXYZ
string.ascii_letters # abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
string.digits # 0123456789
string.punctuation # <=>?@[\]^_`{|}~.
Vamos começar gerando uma senha de 5 caracteres que inclua apenas letras minúsculas:
from random import choice
import string
tamanho = 5
valores = string.ascii_lowercase
senha = ''
for i in range(tamanho):
senha += choice(valores)
print(senha)
Se quisermos gerar uma senha que também contenha números, podemos incluí-los nos valores:
tamanho = 5
valores = string.ascii_lowercase + string.digits
senha = ''
for i in range(tamanho):
senha += choice(valores)
print(senha)
Agora, se quisermos utilizar todas as letras maiúsculas e minúsculas, números e caracteres especiais devemos configurar a variável valores para incluir todos:
valores = string.ascii_letters + string.digits + string.punctuation
Como quebrar uma senha forte
Por que uma senha é considerada forte? Por que uma pessoa maliciosa poderia criar um programa que gera todas as combinações de uma senha de 5 dígitos por exemplo e então tentar fazer login no seu e-mail com todas essas combinações.
Esse é um dos motivos por que os sites normalmente te permitem errar apenas 3 vezes a senha e bloqueiam sua conta caso você erre a quarta tentativa. Mas ainda existem muitos sites por aí que não tem este tipo de segurança. Então o mínimo que você pode fazer é criar uma senha forte para evitar problemas.
Mas como? Acontece que dependendo da quantidade de caracteres e de quais caracteres são incluídos na sua senha, a quantidade de combinações pode ser tão grande que nem mesmo um hacker deve ser capaz de gerar todas elas. Vamos fazer alguns testes para entender isso melhor.
Vamos criar uma função para gerar as senhas.
import string
from itertools import combinations_with_replacement
def gerar_senhas(valores, tamanho):
comb = combinations_with_replacement(valores, tamanho)
print(list(comb))
A função combinations_with_replacement devolve todas as combinações dos valores com o tamanho especificado. Precisamos utilizar esta versão with_replacement pois ela gera as combinações com caracteres repetidos. É preciso transformar o resultado da função em lista para podermos visualizar os resultados.
Quanto tempo demora para quebrar minha senha?
Para medir quanto tempo demora para gerar todas as combinações, vamos utilizar o módulo time.
import time
ini_t = time.time()
gerar_senhas(valores, tamanho)
fin_t = time.time()
print("Tempo: " + str(fin_t - ini_t) + "s")
Marcamos o tempo de inicio e o tempo final e depois fazemos uma subtração para saber quanto tempo se passou.
Veja o resultado com diferentes tamanhos e combinações considerando letras, números e caracteres especiais.
Tamanho da senha | Tempo para quebrar |
4 | 0,45s |
5 | 15s |
6 | 4 min |
7 | 6 horas |
8 | 24 dias |
9 | 6 anos |
10 | 600 anos |
O meu computador não tem memória suficiente para gerar desta forma, por isto para obter os resultados da tabela acima utilizei o site Randomize.
Estou mostrando aqui o método de força bruta, há outros métodos para quebrar senhas, esse é um deles. Mas a próxima vez que for utilizar um site não muito confiável, lembre-se disto, uma senha de no mínimo 10 caracteres com letras maiúsculas, minúsculas, números e caracteres especiais.
E mais importante ainda, não use a mesma senha em mais de um site! Assim você limita o dano causado caso sua senha for quebrada.