Você dev com certeza já mexeu com sisteminhas de hash para garantir a segurança dos usuários, mas e se eu te contar que isso não garante nada hoje em dia? Hackear não é como nos filmes. É metódico, e muito mais assustador.

Hackers não ficam tentando login na tela de autenticação. Isso seria como um ladrão bater na porta do banco. Eles copiam o cofre inteiro e vão pra casa trabalhar com calma. É o que a literatura chama de ataque offline.

O que o banco realmente guarda?

Aplicações bem construídas não armazenam senhas em texto puro. Hash é o resultado de passar sua senha por uma função matemática. O SHA-1 de "senha123" é sempre 7c4a8d09ca3762af61e59520943dc26494f8941b, por exemplo. Determinístico.

O problema começa aqui: se essa conversão é rápida, facilita o trabalho do inimigo.

Pra você ter uma ideia, um hacker com RTX 4090 e hashcat pode testar 164 bilhões de hashes por segundo. Mas como assim testar hashes? Esse sistema pega inúmeras senhas candidatas e aplica o mesmo algoritmo de hash que seu sistema usa. Comparando cada resultado com o hash da senha alvo, se bater, achou.

MD5 e SHA-256 são rápidos por design, já que foram criados para verificar a integridade de arquivos, não proteger senhas.

Por isso, o ideal é mudar o seu conversor para um mais lento, o mesmo que o hacker terá que usar para decifrar seus hashes. É contra-intuitivo para quem passa a vida otimizando código, mas é isso: você quer que o hash demore.

Imagine um ataque de força bruta, se você precisar testar 1 bilhão de combinações:

Com SHA-256: leva segundos

Com bcrypt: leva meses

Com Argon2: leva anos (além de mais lento, ele consome mais memória RAM intencionalmente)

Por que consumir mais memória RAM contribui para dificultar o trabalho do invasor?

O método de conversão de hashes não depende só de uma máquina rápida, mas capaz de fazer muitas tentativas ao mesmo tempo. Argon2 obriga cada tentativa de senha a usar um bloco grande de memória. E memória é muito mais cara que cálculo.

Mas quer dificultar ainda mais? Adicione salt e pepper ao seu sistema.

Senhas iguais sempre irão gerar o mesmo hash. Se a senha de um usuário for descoberta, qualquer outro com a mesma senha também será afetado. Mas, se mudar apenas 1 caractere, o efeito avalanche irá alterar o hash completamente.

Salt é a sementinha da confusão, um valor aleatório único gerado para cada usuário. Essa semente é concatenada à senha e um hash completamente novo é gerado.

Senhas iguais = hashes iguais (desvendou um, já sabe o resto)

Senhas iguais + salts diferentes = hashes distintos.

O salt não é segredo: ele fica armazenado junto com o hash no banco e não precisa ser secreto, já que a função dele é quebrar o efeito manada do ataque.

Diferente do salt, o pepper não é público, mas uma string guardada em variável de ambiente que é adicionada a todas as senhas antes do hash. A lógica é de defesa em profundidade: mesmo que o atacante tenha o dump completo do banco (todos os hashes + todos os salts), sem o pepper ele não consegue reproduzir o hash correto. É separação de superfície de ataque: banco comprometido não implica senhas comprometidas se o pepper está em outro lugar.

Com isso, concluo: Segurança não é apenas uma linha de código. É uma camada de decisões técnicas que precisam ser planejadas e tomadas cedo.