Bcrypt vs Argon2: que hash de palavra-passe em 2026
Bcrypt e Argon2 são as duas funções de hash de palavras-passe mais utilizadas atualmente. Ambas foram concebidas para serem lentas e resistentes a ataques de força bruta, ao contrário de MD5 ou SHA-256, que são rápidas por construção. O Argon2 venceu a Password Hashing Competition em 2015 e é hoje a escolha recomendada pela OWASP para novas aplicações. O Bcrypt continua a ser uma excelente opção, madura e amplamente suportada. Este artigo explica com precisão as diferenças para te ajudar a decidir.
Porque é que um hash de palavra-passe é diferente
Um hash criptográfico clássico como SHA-256 foi concebido para ser rápido: pretende-se processar GB de dados por segundo. Para palavras-passe, essa propriedade é um defeito: um atacante que obtenha a tua tabela de utilizadores pode testar milhares de milhões de palavras-passe por segundo numa GPU. Uma função de hash de palavras-passe (PHF, password hashing function) procura, pelo contrário, ser:
- Lenta por construção, com um parâmetro de custo ajustável
- Com sal, para impedir rainbow tables e ataques paralelos sobre várias contas
- Resistente a hardware especializado (GPU, FPGA, ASIC) para limitar o speedup adversarial
O sal e o parâmetro de custo são armazenados com o hash, numa cadeia única tipicamente
com a forma $algo$params$sal$hash. Isto permite aumentar o custo com o tempo sem
forçar a migração imediata dos hashes antigos.
Bcrypt: 1999, Blowfish, parâmetro cost
O Bcrypt foi concebido por Niels Provos e David Mazières para o OpenBSD em 1999.
Baseia-se no algoritmo de cifra Blowfish, do qual explora o elevado custo de inicialização das
tabelas. O Bcrypt expõe um único parâmetro, cost (ou rounds), que
define o número de iterações na forma 2^cost. Aumentar cost em 1 duplica o tempo de cálculo.
Formato de saída típico:
$2y$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
| | | |
| | cost = 12 sal + hash em base64
| variante (2y = openbsd)
algo bcrypt
O Bcrypt limita a entrada a 72 bytes: uma palavra-passe mais longa é truncada silenciosamente, o que é uma armadilha conhecida. A solução habitual é fazer pré-hash com SHA-256 e depois codificar em base64 antes do bcrypt, mas isto pode introduzir null bytes problemáticos em algumas implementações. O Argon2 não tem essa limitação.
Argon2: 2015, vencedor PHC, 3 variantes
O Argon2 foi concebido por Alex Biryukov, Daniel Dinu e Dmitry Khovratovich. Venceu a Password Hashing Competition em julho de 2015 e está normalizado pelo RFC 9106 (2021). O Argon2 expõe três parâmetros:
- Memory cost (
m): quantidade de memória utilizada, em KiB - Time cost (
t): número de iterações sobre o bloco de memória - Parallelism (
p): número de threads paralelas
O Argon2 existe em três variantes:
- Argon2d: acesso à memória dependente dos dados. Mais resistente a ataques GPU, mas sensível a ataques por canal lateral (timing, cache).
- Argon2i: acesso à memória independente dos dados. Resistente a side-channels, ligeiramente menos resistente a ataques GPU.
- Argon2id: híbrido, começa em modo i e depois passa para modo d. Recomendado por omissão pelo RFC 9106 e pela OWASP.
Os parâmetros recomendados pela OWASP em 2026 para Argon2id: m=19456 KiB (19 MiB),
t=2, p=1. Formato de saída típico:
$argon2id$v=19$m=19456,t=2,p=1$c2VsX2FsZWF0b2lyZQ$aGFzaF9jYWxjdWxl
| | | | |
| | parametros sal base64 hash base64
| versao
algo argon2id
Porque é que o Argon2id é recomendado
A resistência a hardware especializado é hoje o critério decisivo. O Bcrypt utiliza pouca memória (~4 KiB), o que permite a uma GPU topo de gama testar centenas de milhares de hashes por segundo. O Argon2id é memory-hard: forçar vários MiB de memória por tentativa reduz drasticamente o paralelismo atingível em GPU e torna a conceção de ASIC dedicados economicamente inviável.
O modo híbrido do Argon2id oferece ainda proteção contra ataques por canal lateral durante a primeira metade do cálculo. É esta combinação que justifica o seu lugar de recomendação por omissão da OWASP, do NIST SP 800-63B (desde a revisão de 2024) e do RFC 9106.
Tabela comparativa
| Critério | Bcrypt | Argon2id |
|---|---|---|
| Ano | 1999 | 2015 |
| Normalização | De facto, USENIX 1999 | RFC 9106 (2021) |
| Parâmetros | cost | memory, time, parallelism |
| Memória utilizada | ~4 KiB | Configurável (~19 MiB recomendado) |
| Memory-hard | Não | Sim |
| Resistência a GPU | Moderada | Forte |
| Resistência a side-channel | Boa (constant-time) | Boa (modo id) |
| Limite de entrada | 72 bytes | Nenhum |
| Recomendação OWASP 2026 | Aceitável | Preferido |
| Maturidade do ecossistema | Muito ampla | Ampla desde ~2018 |
Desempenho e resistência a ataques
Num servidor moderno, um bcrypt com cost=12 demora cerca de 250 ms e um argon2id com os parâmetros OWASP cerca de 100 a 300 ms consoante a máquina. O tempo absoluto não é o critério: o que importa é a relação entre o teu custo (um cálculo, uma vez por login) e o do atacante (milhares de milhões de cálculos em GPU para quebrar um dump).
Numa RTX 4090, o hashcat atinge cerca de 200 000 bcrypt/s com cost=12, contra algumas dezenas de milhares de argon2id a 19 MiB. Para o mesmo tempo de cálculo do lado do servidor, o Argon2id atrasa o atacante 5 a 10 vezes mais do que o bcrypt, e a diferença aumenta com as novas gerações de GPU.
Exemplos PHP
O PHP suporta ambos nativamente através de password_hash() e password_verify()
desde o PHP 7.2 para Argon2i (e 7.3 para Argon2id). O construtor PHP gere sal e formato
automaticamente.
Bcrypt
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
$ok = password_verify($password, $hash);
if (password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 12])) {
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
}
Argon2id
$opts = [
'memory_cost' => 19456, // 19 MiB
'time_cost' => 2,
'threads' => 1,
];
$hash = password_hash($password, PASSWORD_ARGON2ID, $opts);
$ok = password_verify($password, $hash);
if (password_needs_rehash($hash, PASSWORD_ARGON2ID, $opts)) {
$hash = password_hash($password, PASSWORD_ARGON2ID, $opts);
}
Podes gerar ou identificar hashes de todos os tipos com o nosso gerador de hash e o nosso identificador de hash.
Recomendação
Para uma nova aplicação em 2026, escolhe Argon2id com os parâmetros OWASP como
baseline (m=19456, t=2, p=1), a ajustar conforme o tempo
pretendido (tipicamente 250 a 500 ms). Se manténs uma aplicação existente em bcrypt, não há
urgência em migrar: bcrypt com cost=12 ou superior continua seguro em 2026. Aproveita um
password_needs_rehash() no próximo login para migrar progressivamente os
utilizadores ativos para Argon2id.
Evita absolutamente MD5, SHA-1 e SHA-256 simples para palavras-passe (ver o nosso comparativo MD5 vs SHA-256). Nenhum destes algoritmos foi concebido para esse uso.
Perguntas frequentes
O Bcrypt ainda é seguro em 2026?
Sim, desde que se utilize um cost suficiente (12 no mínimo, 14 se possível). O Bcrypt não tem nenhuma falha criptográfica conhecida. A sua única fraqueza relativa face ao Argon2id é a sua reduzida utilização de memória, que o torna mais acessível a ataques GPU e FPGA.
É preciso migrar uma base bcrypt para Argon2id?
Não com urgência. Uma migração progressiva com password_needs_rehash() é a
abordagem recomendada: a cada login bem-sucedido, voltas a calcular o hash da palavra-passe
em Argon2id. Ao fim de alguns meses, a maioria dos utilizadores ativos está migrada, e podes
forçar uma reposição para as contas inativas.
Qual é o número correto de threads para Argon2id?
A OWASP recomenda p=1 por omissão. Aumentar p não traz nada se o
teu servidor web já trata muitos pedidos em paralelo, e complica o tuning. Prefere antes
aumentar m (memória), que é a principal alavanca de resistência a GPU.
O que é um « bcrypt decrypter »?
Não existe um descodificador bcrypt: a função é de sentido único por construção. As ferramentas que afirmam « descodificar » bcrypt limitam-se a testar dicionários de palavras-passe comuns contra o hash. É exatamente o mesmo que faria um atacante que tivesse a tua tabela.
Argon2i ou Argon2id?
Argon2id em todos os casos para palavras-passe. O Argon2i é ligeiramente mais seguro face a side-channels, mas mais fraco face a ataques GPU. O Argon2id combina as vantagens de ambos e é explicitamente recomendado pelo RFC 9106 para o hash de palavras-passe.
É preciso aplicar pepper além do sal?
O sal é suficiente para a grande maioria das aplicações. Um pepper (chave secreta armazenada fora da base de dados e usada como HMAC antes do hash) acrescenta uma camada em caso de fuga da base sem comprometimento do servidor aplicacional. O Argon2id não o fornece nativamente, é preciso compô-lo manualmente.