bcrypt para hash de senhas Por que a criptografia sozinha não é suficiente
Se você estiver armazenando senhas de usuários com AES, RSA ou até mesmo SHA-256, está fazendo isso errado. Não errado de forma leve — errado de forma fundamental. Este é o erro de segurança mais comum na desenvolvimento web, e tem uma solução direta: use uma função adequada de hash de senha, como o bcrypt.
Aqui está por que isso importa, como o bcrypt funciona e como o código pronto para produção se apresenta.
Por que as senhas precisam de tratamento especial
As maioria das operações criptográficas são projetadas para serem reversíveis ou rápidas. A criptografia é reversível por design — isso é seu propósito inteiro. SHA-256 e MD5 são rápidas, processando gigabytes por segundo. Essas duas propriedades são catastróficas para senhas.
Quando um atacante obtém seu banco de dados, ele obtém seus hashes de senhas. Com criptografia, se eles encontrarem a chave, eles descodificam tudo. Com hashes rápidos como MD5 ou SHA-256, eles executam um ataque de força bruta acelerado por GPU — a hardware moderno pode testar bilhões de hashes MD5 por segundo. Sua “complexa” senha é quebrada em minutos.
As senhas precisam ser:
- Não reversíveis — mesmo com a chave ou o algoritmo, você não consegue obter o texto claro de volta
- Lentas para calcular — a lentidão deliberada torna os ataques de força bruta impraticáveis
- Únicas por usuário — senhas idênticas devem produzir hashes diferentes
O bcrypt satisfaz todas as três. As funções de hash genéricas e a criptografia não o fazem.
Hashing vs Criptografia vs Hash de Senha
Essas não são intercambiáveis:
| Abordagem | Reversível? | Rápido? | Seguro para senhas? |
|---|---|---|---|
| Criptografia (AES, RSA) | Sim — com a chave | Sim | Não |
| Hash rápido (MD5, SHA-256) | Não | Sim (por design) | Não |
| Hash de senha (bcrypt, Argon2id) | Não | Não (por design) | Sim |
A reversibilidade da criptografia é um ponto crítico: comprometer a chave compromete todas as senhas. O rápido hashing também é um ponto crítico: a velocidade permite ataques de força bruta. As funções de hash de senha são projetadas para serem lentas — e isso é o ponto.
Como o bcrypt funciona
O bcrypt, desenvolvido em 1999 por Niels Provos e David Mazières, realiza três coisas importantes:
1. Salting. Antes de hashar, o bcrypt gera um sal aleatório (16 bytes) e o inclui na saída do hash. Mesmo que dois usuários tenham a mesma senha, seus hashes são diferentes. Isso elimina completamente os ataques com tabelas de rainbow pré-calculadas.
2. Fator de trabalho (custo). O bcrypt aceita um parâmetro de custo (normalmente 10–14). Cada incremento dobra o tempo de cálculo. No custo 12, o hash leva aproximadamente 250–400ms em hardware moderno. Isso é lentamente perceptível para uma solicitação de login — mas transforma um ataque de força bruta com bilhões de tentativas em uma operação que dura décadas.
3. A saída é autocontida. Um hash bcrypt parece $2b$12$... e codifica a versão do algoritmo, o fator de custo, o sal e o hash juntos. Você não precisa de uma coluna separada para o sal. Armazene a string inteira.
Código de produção: Node.js e Python
Node.js (bcryptjs ou bcrypt)
const bcrypt = require('bcrypt');
const SALT_ROUNDS = 12;
// Hash a password
async function hashPassword(plaintext) {
return bcrypt.hash(plaintext, SALT_ROUNDS);
}
// Verify a password against a stored hash
async function verifyPassword(plaintext, storedHash) {
return bcrypt.compare(plaintext, storedHash);
}
// Usage
const hash = await hashPassword('hunter2');
// Store `hash` in your database
const isValid = await verifyPassword('hunter2', hash);
// true
Python (bcrypt)
import bcrypt
COST = 12
def hash_password(plaintext: str) -> bytes:
salt = bcrypt.gensalt(rounds=COST)
return bcrypt.hashpw(plaintext.encode('utf-8'), salt)
def verify_password(plaintext: str, stored_hash: bytes) -> bool:
return bcrypt.checkpw(plaintext.encode('utf-8'), stored_hash)
# Usage
hashed = hash_password('hunter2')
# Store hashed in your database
is_valid = verify_password('hunter2', hashed)
# True
Armazene a string completa do hash. Nunca armazene o texto claro, nunca armazene o sal separadamente, nunca armazene os valores intermediários.
Você pode testar o hashing do bcrypt interativamente com o
O fator de custo correto depende do seu hardware. O objetivo: tornar cada operação de hash levar 200–500ms no seu servidor de produção. Isso é rápido o suficiente para uma boa experiência do usuário, lento o suficiente para frustrar os atacantes.
Recomendação atual: custo 12 como mínimo, 14 para contas de alto valor (administrador, financeiro). Faça uma benchmark no seu hardware real:
// Node.js: benchmark different cost factors
const bcrypt = require('bcrypt');
for (let cost = 10; cost <= 14; cost++) {
const start = Date.now();
await bcrypt.hash('benchmark', cost);
console.log(`Cost ${cost}: ${Date.now() - start}ms`);
}
Se o custo 12 levar menos de 100ms, aumente. Se o custo 14 levar mais de 1000ms, reduza para 13. Revise anualmente — o hardware se torna mais rápido, e seu fator de custo deve acompanhar.
Você pode testar a hashificação com bcrypt interativamente com o IO Tools bcrypt Hash Generator.
bcrypt vs Argon2id vs scrypt
O bcrypt é testado e amplamente suportado. Mas tem uma limitação: não é difícil de memória. Um atacante com hardware especializado (ASICs ou FPGAs) pode paralelizar ataques com mais eficiência do que com alternativas baseadas em memória.
| Algoritmo | Difícil de memória | Resistente à paralelização | Recomendação |
|---|---|---|---|
| bcrypt | Não | Parcial | Boa opção padrão; use custo ≥12 |
| scrypt | Sim | Parcial | Melhor que o bcrypt, menos ferramentas |
| Argon2id | Sim | Sim | Recomendado para novos projetos |
Para novos projetos: use Argon2id. Ganhou a Concorrência de Hash de Senha (2015), é difícil de memória, resiste a ataques de GPU e ASIC, e está agora na recomendação do OWASP. A API é quase idêntica ao bcrypt.
Para projetos existentes: se você já está usando bcrypt com um fator de custo razoável, a migração não é urgente. Adicione isso à sua próxima refatoração principal.
Erros comuns na implementação
Hashando o hash. Alguns desenvolvedores hasham a senha no lado do cliente antes de enviar, e depois hasham novamente no lado do servidor. O hash do lado do cliente se torna a “senha”. Agora você está hashando uma string de hexa de comprimento fixo, e não uma senha escolhida pelo usuário — você perde nada com o duplo hash, mas também não ganha nada, e introduz confusão.
O problema da truncação de 72 bytes. O bcrypt ignora silenciosamente tudo além de 72 bytes. Uma senha de 100 caracteres e uma senha de 72 caracteres que compartilham os primeiros 72 bytes são idênticas para o bcrypt. Se seus usuários definirem senhas muito longas, isso representa uma degradação silenciosa de segurança. Mitigação: hash com SHA-256 antes de passar para o bcrypt — mas apenas se você entender plenamente as implicações, e documentar claramente.
Fator de trabalho fraco. O custo 10 era razoável em 2011. Em 2026, use pelo menos 12. Se seus registros existentes usam custo 10, você pode atualizar transparentemente: após um login bem-sucedido, re-hash a senha verificada com o novo custo e armazene o hash atualizado.
A sincronia importa. O bcrypt é intensivo em CPU. Sempre use a API assíncrona (como mostrado acima) no Node.js para evitar bloquear o loop de eventos. O bcrypt síncrono em um servidor Node fará cada outra requisição esperar.
Migração de MD5/SHA para bcrypt
Você não pode re-hashar sem o texto claro original. Mas você pode migrar oportunisticamente:
- Adicione uma
password_hashcoluna ao lado da antigapassword_md5coluna - Em um login bem-sucedido (quando você tem o texto claro), hash com bcrypt e armazene em
password_hash, remova a coluna antiga - Após um período de migração, os usuários que não logaram podem ser forçados a resetar suas senhas
- Uma vez
password_md5está vazia para todos os usuários, remova a coluna
Este é o método padrão e exige nenhum tempo de inatividade.
O Resultado Final
A criptografia é para dados que você precisa recuperar. O hashing é para dados que você precisa verificar. As senhas devem ser verificadas, não recuperadas — o que significa que a criptografia é a ferramenta errada.
O bcrypt dá a você salting, lentidão configurável e um formato de hash autocontido. Foi a resposta correta há 25 anos. Use-o com custo 12 ou superior, use Argon2id para novos projetos e migre dos MD5 e SHA-256 o mais cedo possível.
Errar nisso não é um risco hipotético. Bancos de dados são violados. Quando isso acontece, senhas corretamente hashadas com bcrypt são computacionalmente impraticáveis de serem quebradas. Os hashes MD5 são quebrados em poucas horas.
Instale nossas extensões
Adicione ferramentas de IO ao seu navegador favorito para acesso instantâneo e pesquisa mais rápida
恵 O placar chegou!
Placar é uma forma divertida de acompanhar seus jogos, todos os dados são armazenados em seu navegador. Mais recursos serão lançados em breve!
Ferramentas essenciais
Ver tudo Novas chegadas
Ver tudoAtualizar: Nosso ferramenta mais recente foi adicionado em 27 abr, 2026
