Pular para o conteúdo
>_ITDITDPlataforma de Segurança Web

Guias de Segurança

Como armazenar senhas com segurança — a forma certa de fazer hash e salt

Como você deve armazenar as senhas dos usuários? Por que texto puro, criptografia e hashes crus falham, o que um salt por usuário faz e a resposta de verdade — um hash lento (bcrypt/Argon2/scrypt): como escolher, ajustar e migrar um sistema existente. Defensivo e voltado para devs, sem passos de ataque.

Publicado 2026-06-27 Atualizado 2026-06-27 5 min de leitura

"Como exatamente devo armazenar as senhas dos usuários no banco de dados?" — todo construtor esbarra nessa pergunta uma vez. A resposta é clara. Aqui está a forma segura de armazená-las, em ordem, sem passos de ataque.

Por que texto puro, criptografia e hashes crus falham

Presuma que o banco de dados vai vazar algum dia. Quando vazar, o dano difere muito conforme o método de armazenamento.

  • Texto puro: toda senha é exposta no instante em que vaza. Pior, a reutilização de senhas encadeia a invasão para os outros serviços do usuário. O pior caso.
  • Criptografia (reversível): a chave a reverte — então se a chave vazar junto, você volta ao texto puro. Uma senha nunca precisa ser lida de volta, então ser reversível não traz benefício nenhum.
  • Hash cru (MD5/SHA-256): um hash rápido permite ao atacante testar tentativas rapidamente. Senhas comuns caem para rainbow tables e força bruta.

Os "quatro estágios" até o seguro

É mais rápido entender adicionando uma correção por vez a um método fraco.

1. texto puro: fim de jogo se vazar
↓ torne-o de mão única
2. hash cru: fraco contra rainbow tables
↓ adicione um salt por usuário
3. hash com salt: tabelas derrotadas, mas a força bruta ainda é rápida
↓ torne-o deliberadamente lento
4. hash com salt + lento (Argon2id / bcrypt): esta é a resposta
texto puro → hash cru → com salt → hash lento. Só no fim é realmente 'armazenamento seguro'.

A percepção-chave: um salt e um hash lento fazem trabalhos diferentes. Um salt derrota a pré-computação (rainbow tables) e a quebra em massa por reutilização. Um hash lento reduz a força bruta a uma taxa impraticável. Você precisa dos dois antes de estar seguro (→ o que é hashing).

Na prática: o que fazer agora

1

Use Argon2id (ou bcrypt)

Para sistemas novos, faça do Argon2id a primeira escolha — ele também pode exigir memória, o que resiste à força bruta por GPU. Se você prefere uma implementação testada em batalha, o bcrypt é mais do que suficiente na prática. Use a implementação da biblioteca padrão como está para qualquer um dos dois.

2

Deixe o salt ser automático

bcrypt/Argon2 geram um salt por usuário e o embutem dentro da string de hash. Você não mantém uma coluna de salt separada. Montar à mão MD5(salt + senha) é o clássico que não se deve fazer.

3

Ajuste o custo para o seu ambiente

Defina o fator de custo do bcrypt, ou memória/iterações/paralelismo do Argon2, o mais alto que conseguir enquanto um login legítimo ainda parecer instantâneo. Conforme os servidores ficam mais rápidos, os atacantes também — revisite e eleve anualmente.

4

Verifique com a função de comparação padrão

No login, compare a entrada com o hash armazenado usando a função de verificação da biblioteca (a maioria usa uma comparação de tempo constante, segura contra timing). Não escreva sua própria igualdade de strings.

5

Migre hashes fracos refazendo o hash no login

Se você já armazena MD5/SHA-256, no momento em que um usuário faz login com sucesso, refaça o hash com o novo esquema e salve. Para usuários que não fizeram login, você pode atualizar provisoriamente envolvendo o hash existente dentro do bcrypt (um hash em camadas).

Erros comuns vs. a implementação correta

Erro comum

  • Criptografar senhas para armazenar (chave vaza → acabou)
  • Armazenar MD5(senha) ou SHA-256(senha) diretamente
  • Usar um único salt compartilhado para todos os usuários
  • Montar à mão hash(salt + senha)

Implementação correta

  • Hash de mão única com Argon2id / bcrypt
  • Um salt por usuário (a biblioteca o adiciona automaticamente)
  • Custo o mais alto que parecer OK, elevado periodicamente
  • Usar as funções padrão de hash/verificação como estão

A visão deste site: armazenamento de senha é lugar de seguir a resposta chata e comprovada

Armazenamento de senha não é lugar de ser criativo. Seguir as implementações padrão do Argon2/bcrypt, testadas pelo mundo todo, é o mais seguro e o mais fácil de operar. Nossa posição: não inove aqui. Gaste seu esforço, em vez disso, em reduzir a dependência de senhas em siautenticação multifator (MFA) minuciosa e uma eventual migração para passkeys (sem senha). Nem o hash mais forte salva uma senha fraca e reutilizada.

Leia a seguir

FAQ

QNão basta criptografar as senhas para armazenar?
A

Não — criptografia é a ferramenta errada. Criptografia é reversível com uma chave, então se a chave vazar, toda senha volta a texto puro. Uma senha nunca precisa ser lida de volta, nem por você, então um 'hash' irreversível é a resposta certa. Mas um hash cru não basta; combine um salt por usuário com um hash lento (bcrypt/Argon2).

Qbcrypt ou Argon2 — qual usar?
A

Para desenvolvimento novo, o Argon2 (Argon2id especialmente) é a primeira escolha: permite ajustar memória e processamento, o que resiste bem à força bruta por GPU. Se você valoriza uma implementação consagrada e testada em batalha, o bcrypt ainda é perfeitamente prático. O ponto-chave em qualquer um é usar a implementação da biblioteca padrão como está e não inventar a sua.

QEu já armazenei senhas com MD5/SHA-256. Como migro?
A

Você não consegue converter em massa de volta para texto puro (esse é o ponto), então migre no login. No momento em que um usuário faz login com sucesso, refaça o hash da senha correta que ele acabou de digitar com o novo esquema (ex.: Argon2id) e salve. Para usuários que não fizeram login, você pode atualizar provisoriamente envolvendo o hash existente dentro do bcrypt (um hash em camadas).