Uma violação de dados que expõe as senhas dos seus usuários é um evento catastrófico. Se essas senhas forem armazenadas em texto puro — ou com hash MD5/SHA — atacantes poderão quebrá-las em minutos. O hashing de senhas adequado é a última linha de defesa. Este guia explica o que usar, por quê e como.
Por Que Armazenar Senhas em Texto Puro é Inaceitável
Se o seu banco de dados for invadido e as senhas estiverem armazenadas em texto claro, a senha de cada usuário estará imediatamente comprometida. Como a maioria dos usuários reutiliza senhas em diferentes serviços, uma violação no seu site pode levar à invasão de suas contas bancárias, e-mail e redes sociais.
Por Que MD5 e SHA São Inadequados para Senhas
MD5 e SHA-256 são funções de hash de propósito geral. Elas foram projetadas para serem rápidas — o SHA-256 pode processar bilhões de hashes por segundo em uma GPU moderna. Isso é exatamente o que você não quer para senhas.
Algoritmo Hashes/Segundo (GPU) Tempo para quebrar senha de 8 caracteres ───────────────────────────────────────────────────────────────────── MD5 200 bilhões Segundos SHA-256 10 bilhões Minutos bcrypt (custo 12) 5.000 Milhares de anos Argon2id 1.000 Milhões de anos
O Que Torna um Hash de Senha Bom?
- Intencionalmente lento: Leva de 100ms a 500ms por hash. Rápido o suficiente para login, muito lento para ataques de força bruta.
- Fator de custo ajustável: Conforme o hardware evolui, você aumenta o custo para manter o hashing lento.
- Sal integrado: Cada senha recebe um 'salt' (sal) aleatório e único, fazendo com que senhas idênticas gerem hashes diferentes.
- Resistente à memória (moderno): Requer uma quantidade significativa de memória por hash, tornando ataques baseados em GPU impraticáveis.
Os Três Gigantes: bcrypt, scrypt, Argon2
bcrypt (1999)
O padrão da indústria por duas décadas. Resistente à CPU, mas não à memória. Ainda excelente e amplamente suportado.
import bcrypt from 'bcryptjs';
// Gerar hash de uma senha (fator de custo 12 — leva ~300ms)
const hash = await bcrypt.hash("senhaDoUsuario123", 12);
// → "$2b$12$LJ3m4ys3Lz7g..."
// Verificar uma senha
const isValid = await bcrypt.compare("senhaDoUsuario123", hash);
// → true
Argon2id (2015 — Recomendado)
Vencedor da Competição de Hashing de Senhas de 2015. Resistente tanto à CPU quanto à memória. A melhor opção para novos projetos.
import argon2 from 'argon2';
// Gerar hash de uma senha
const hash = await argon2.hash("senhaDoUsuario123", {
type: argon2.argon2id, // Variante recomendada
memoryCost: 65536, // 64 MB
timeCost: 3, // 3 iterações
parallelism: 4 // 4 threads
});
// Verificar
const isValid = await argon2.verify(hash, "senhaDoUsuario123");
A Função nativa do PHP `password_hash()`
// Gerar hash — usa bcrypt por padrão, Argon2id disponível em PHP 7.3+
$hash = password_hash("senhaDoUsuario123", PASSWORD_ARGON2ID);
// Verificar
if (password_verify("senhaDoUsuario123", $hash)) {
echo "Senha correta!";
}
// Verificar se o hash precisa de rehash (ex: fator de custo aumentado)
if (password_needs_rehash($hash, PASSWORD_ARGON2ID)) {
$newHash = password_hash("senhaDoUsuario123", PASSWORD_ARGON2ID);
// Atualizar hash no banco de dados
}
O Que é Salting (Sal)?
Um 'salt' é uma string aleatória adicionada à senha antes de gerar o hash. Sem salts, todos os usuários com a senha "senha123" terão o mesmo hash — atacantes podem usar tabelas pré-computadas (tabelas arco-íris) para quebrá-las instantaneamente. Com salts, cada hash é único, mesmo para senhas idênticas.
Boas notícias: bcrypt, scrypt e Argon2 gerenciam o salting automaticamente. Você não precisa se preocupar em gerenciar salts manualmente.
Melhores Práticas
- Use Argon2id para novos projetos. Utilize bcrypt como alternativa se Argon2 não estiver disponível.
- Nunca use MD5, SHA-1 ou SHA-256 para hashing de senhas.
- Nunca escreva sua própria lógica de hashing. Use bibliotecas comprovadas.
- Aumente o fator de custo à medida que o hardware melhora. Mire em 200-500ms por hash.
- Implemente limite de taxa nos endpoints de login para prevenir ataques de força bruta online.
- Dê suporte a gerenciadores de senhas — não defina limites máximos de comprimento de senha abaixo de 64 caracteres.
- Considere adicionar 'pepper' — uma chave secreta misturada ao hash, armazenada separadamente do banco de dados.
Experimente Nossas Ferramentas Gratuitas de Codificação
Codifique e decodifique Base64, usado em cabeçalhos de autenticação HTTP.