Como gerar senhas fortes com Random em Python

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 senhaTempo para quebrar
40,45s
515s
64 min
76 horas
824 dias
96 anos
10600 anos
Tempo que leva para quebar uma senha

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.