bcrypt vs Argon2: escolhendo configurações de hashing de senhas
bcrypt vs Argon2 explicado: compare características de segurança, custos de desempenho no mundo real e como escolher parâmetros seguros para backends web modernos.

Que problema o hashing de senhas resolve
O hashing de senhas permite que um backend armazene uma senha sem guardar a senha em si. Quando alguém se cadastra, o servidor passa a senha por uma função unidirecional e salva o resultado (o hash). No login, ele hasheia a senha digitada pelo usuário e compara com o que foi salvo.
Um hash não é criptografia. Não há como descriptografá-lo. Essa propriedade unidirecional é exatamente o motivo de usarmos hashing para senhas.
Então por que não usar um hash rápido comum como SHA-256? Porque "rápido" é justamente o que atacantes desejam. Se um banco de dados for roubado, atacantes não adivinham senhas tentando logar uma a uma. Eles fazem adivinhação offline com a lista de hashes roubada, empurrando palpites tão rápido quanto o hardware permite. Com GPUs, hashes rápidos podem ser testados em escala enorme. Mesmo com salts únicos, um hash rápido ainda é barato de força bruta.
Aqui está um modo de falha realista: um pequeno app web perde sua tabela de usuários em um vazamento. O atacante obtém e-mails e hashes de senha. Se esses hashes foram gerados com uma função rápida, senhas comuns e pequenas variações caem rápido. Depois o atacante testa a mesma senha em outros sites (credential stuffing) ou usa para acessar recursos com maiores privilégios dentro do seu app.
Um bom hash de senha torna a adivinhação cara. O objetivo não é “inquebrável”, é “lento e caro demais para valer a pena”.
Uma configuração de hashing de senha deve ser:
- Unidirecional (verificar, não reverter)
- Lenta por tentativa
- Cara para hardware paralelo (especialmente GPUs)
- Rápida o suficiente para que logins reais ainda pareçam normais
- Ajustável para que você possa aumentar o custo ao longo do tempo
bcrypt e Argon2, em um minuto
Quando você compara bcrypt vs Argon2, está escolhendo como vai desacelerar a adivinhação de senhas após um vazamento de banco de dados.
bcrypt é a opção mais antiga e amplamente suportada. Foi projetado para ser caro em CPU e tem um ajuste principal: o fator de custo. Também é “sem surpresas” no bom sentido: fácil de encontrar em bibliotecas, simples de implantar e previsível.
Argon2 é mais novo e foi feito para ser memory-hard. Pode forçar cada tentativa de senha a usar uma quantidade significativa de RAM, não apenas CPU. Isso importa porque atacantes frequentemente vencem executando enormes quantidades de tentativas em paralelo em GPUs ou hardware especializado. Memória é mais difícil e cara de escalar nesse tipo de paralelismo.
Argon2 tem três variantes:
- Argon2i: enfatiza resistência a certos ataques por canais laterais
- Argon2d: enfatiza resistência a GPUs, com considerações sobre canais laterais
- Argon2id: mistura prática de ambos, e o default comum para hashing de senhas
Se sua stack suportar Argon2id e você puder ajustar memória com segurança, geralmente é a melhor escolha moderna. Se precisar de máxima compatibilidade com sistemas mais antigos, bcrypt ainda é sólido quando configurado com um fator de custo alto o suficiente.
Propriedades de segurança que importam mais
A questão central é simples: se um atacante roubar o banco de dados de senhas, quão caro é adivinhar senhas em escala?
Com bcrypt, você controla o custo (fator de trabalho). Custo maior significa que cada tentativa demora mais. Isso desacelera atacantes e também suas próprias verificações de login, então ajuste até ficar penoso para atacantes, mas aceitável para usuários.
Com Argon2id, você pode adicionar memory-hardness além do custo de tempo. Cada tentativa exige CPU e RAM acessada num padrão específico. GPUs são extremamente rápidas em trabalho intensivo de computação, mas perdem muita vantagem quando cada tentativa paralela precisa de memória substancial.
Salts são inegociáveis. Um salt aleatório e único por senha:
- evita que tabelas pré-computadas sejam reutilizadas no banco todo
- garante que senhas idênticas não produzam hashes idênticos entre usuários
Salts não tornam senhas fracas fortes. Eles protegem você após um vazamento ao forçar o atacante a fazer trabalho real por usuário.
Forças e limites do bcrypt que você deve conhecer
bcrypt ainda é amplamente usado, principalmente porque é fácil de implantar em qualquer lugar. Ele costuma ser uma boa escolha quando você precisa de ampla interoperabilidade, quando sua stack tem opções criptográficas limitadas, ou quando quer um único controle simples.
O maior "pegadinha" é o limite de 72 bytes. bcrypt usa apenas os primeiros 72 bytes da senha e ignora o restante. Isso pode surpreender quem usa frases-senha longas ou gestores de senha.
Se escolher bcrypt, deixe explícito o comportamento com comprimento de senha. Ou imponha um comprimento máximo (em bytes, não em caracteres) ou trate entradas longas de forma consistente entre serviços. O importante é evitar truncamento silencioso que mude o que o usuário pensa ser sua senha.
bcrypt também é menos resistente ao hardware paralelo moderno do que opções memory-hard. Sua defesa continua válida, mas depende fortemente de escolher um fator de custo que mantenha cada tentativa cara.
Se estiver construindo um sistema novo ou tiver contas de alto valor (planos pagos, funções admin), migrar novos hashes para Argon2id enquanto continua aceitando bcrypt antigos até o usuário logar é um caminho comum e de baixo risco.
Forças e trocas do Argon2
Argon2 foi feito para hashing de senhas. Argon2id é a variante que a maioria das equipes escolhe porque equilibra resistência a GPUs com proteção razoável contra canais laterais.
Argon2id oferece três parâmetros:
- Memória (m): quanta RAM cada hash usa enquanto roda
- Tempo/iterações (t): quantas passagens são feitas sobre essa memória
- Paralelismo (p): quantas lanes usa (ajuda em CPUs multicore)
Memória é a principal vantagem. Se cada tentativa requer uma quantidade significativa de RAM, atacantes não podem rodar tantas tentativas em paralelo sem pagar caro por capacidade e largura de banda de memória.
A desvantagem é operacional: mais memória por hash significa menos logins concorrentes antes de seus servidores sentirem pressão. Se colocar memória demais, picos de login podem causar enfileiramento, timeouts ou até falhas por falta de memória. Também é preciso pensar em abuso: muitas tentativas concorrentes podem virar um problema de recurso se você não limitar trabalho.
Para manter Argon2id seguro e utilizável, ajuste como se fosse uma característica de performance:
- faça benchmarks em hardware parecido com o de produção
- limite o trabalho de hashing concorrente (caps de workers, filas)
- limite taxa de tentativas e bloqueie falhas repetidas
- mantenha as configurações consistentes entre serviços para que um endpoint fraco não vire alvo
Custos de desempenho em backends web reais
Com hashing de senha, “mais rápido é melhor” geralmente é objetivo errado. Você quer que cada tentativa seja cara para atacantes enquanto logins continuam responsivos para usuários reais.
Uma forma prática é escolher um orçamento de tempo por verificação no seu hardware real de produção. Muitas equipes miram algo como 100 a 300 ms por verificação de hash, mas o número certo depende do seu tráfego e servidores. A diferença entre bcrypt e Argon2 é o que está sendo gasto: bcrypt é majoritariamente CPU, enquanto Argon2 pode também reservar memória.
Escolha um tempo-alvo e meça
Escolha um tempo-alvo por hash e teste em condições que lembrem produção. Meça tanto hashing no cadastro/alteração de senha quanto na verificação do login, mas trate o login como o caminho quente.
Um plano leve de medição:
- teste 1, 10 e 50 verificações de login concorrentes e registre latência p50 e p95
- repita execuções para reduzir ruído de cache e escalonamento de CPU
- meça a chamada ao banco separadamente para saber quanto o hashing realmente custa
- teste com o mesmo container e limites de CPU que você deploya
Picos importam mais que médias
A maioria dos sistemas falha em picos. Se um e-mail traz uma onda de usuários pro login, suas configurações de hashing decidem se o sistema se mantém responsivo.
Se uma verificação leva 250 ms e seu servidor aguenta 40 em paralelo antes de enfileirar, um pico de 500 tentativas pode virar esperas de vários segundos. Nessa situação, uma pequena redução de custo mais limites de taxa fortes pode melhorar a segurança real mais do que empurrar parâmetros ao ponto de fragilizar o endpoint de login.
Mantenha o login interativo previsível
Nem toda operação de senha precisa ter a mesma urgência. Mantenha o custo do login interativo estável e faça trabalho pesado fora do caminho crítico. Um padrão comum é rehash-on-login (atualizar o hash do usuário logo após um login bem-sucedido) ou jobs em background para migrações e importações.
Como escolher parâmetros passo a passo
Ajustar parâmetros é sobre aumentar o custo por tentativa do atacante sem deixar logins lentos ou desestabilizar servidores.
-
Escolha um algoritmo bem suportado pela sua stack. Se Argon2id estiver disponível e bem suportado, geralmente é a escolha padrão. Se precisar de compatibilidade ampla, bcrypt ainda funciona.
-
Defina um tempo-alvo por hash em hardware parecido com o de produção. Escolha algo que mantenha logins suaves durante picos.
-
Ajuste para atingir esse tempo. No bcrypt, ajuste o fator de custo. No Argon2id, balanceie memória, iterações e paralelismo. Memória é a alavanca que mais muda a economia do atacante.
-
Armazene algoritmo e configurações com o hash. Muitos formatos padrão já embutem esses detalhes. Garanta também que o campo no banco é longo o suficiente para que hashes nunca sejam truncados.
-
Planeje upgrades com rehash-on-login. Quando um usuário faz login, se o hash armazenado usar configurações mais fracas que sua política atual, rehash e substitua.
Um ponto de partida prático
Se precisar de um baseline antes de medir, comece conservador e ajuste por tempo.
- Para bcrypt, muitas equipes começam perto do custo 12 e ajustam conforme medições reais.
- Para Argon2id, um baseline comum é memória na casa de dezenas a algumas centenas de MB, custo de tempo 2 a 4, e paralelismo 1 a 2.
Trate esses números como pontos de partida, não regras. As configurações certas se encaixam no seu tráfego, hardware e picos de login.
Erros comuns que enfraquecem o armazenamento de senhas
A maioria das falhas vem de lacunas de configuração, não do algoritmo em si.
Erros com salt são grandes. Cada senha precisa de um salt único armazenado com o hash. Reusar salts, ou usar um salt global para todos os usuários, facilita que atacantes reaproveitem trabalho e comparem contas.
Negligência com custo é outra. Equipes frequentemente lançam com custo baixo porque o login é mais rápido, e nunca revisitam. Hardware melhora, atacantes escalam, e suas configurações que eram adequadas ficam baratas de quebrar.
Excesso de ajuste do Argon2 também é comum. Colocar memória extremamente alta pode parecer bom no papel, mas causar logins lentos, filas de requisição ou erros de falta de memória em picos.
Tratamento do comprimento da senha importa, especialmente com o comportamento de 72 bytes do bcrypt. Se permitir senhas longas e truncá-las silenciosamente, você cria comportamento confuso e reduz segurança.
Algumas práticas que evitam a maior parte desses problemas:
- use salts únicos por senha (deixe a biblioteca gerá-los)
- faça testes de carga e revise configurações periodicamente
- ajuste memória do Argon2 para picos de tráfego, não só para testes isolados
- deixe limites de comprimento de senha explícitos e consistentes
- coloque limites de concorrência e monitoramento no endpoint de login
Checklist rápido para uma configuração mais segura
Mantenha esta lista curta ao liberar e ao mudar infra:
- Salt único por senha, gerado aleatoriamente e armazenado com o hash
- Custo de hashing que aguenta pico de tráfego, verificado com testes de carga em hardware parecido com produção
- Parâmetros armazenados com o hash, para verificar contas antigas e aumentar custo depois
- Controles contra ataques online, incluindo limites de taxa e bloqueios curtos para falhas repetidas
- Um caminho de atualização, normalmente rehash-on-login
Um check simples: rode um teste em staging que inclua um pico de logins (bem-sucedidos e falhos) e observe latência ponta a ponta, uso de CPU e RAM. Se o caminho de login sofrer, ajuste custo e aperte limites de taxa. Não “corrija” cortando itens essenciais como salts.
Um exemplo realista: ajuste para um pequeno app web
Imagine um pequeno SaaS com alguns milhares de usuários. A maior parte do dia é estável, mas você vê picos curtos de login após um newsletter ou no começo do expediente. É aí que a escolha vira planejamento de capacidade.
Você opta por Argon2id para aumentar o custo de cracking offline. Escolha um tempo-alvo de verificação no seu hardware real (por exemplo, 100 a 250 ms), então ajuste parâmetros para atingir isso enquanto monitora RAM, porque configurações de memória podem limitar quantos logins você processa ao mesmo tempo.
Um loop prático de ajuste:
- comece com iterações e paralelismo modestos
- aumente memória até que a concorrência fique desconfortável
- ajuste iterações para afinar o custo de tempo
- reteste com rajadas simuladas, não apenas requisições únicas
Se já tiver hashes antigos com configurações mais fracas, continue verificando-os mas atualize silenciosamente. Ao fazer login com sucesso, rehash com as configurações atuais e salve o novo valor. Com o tempo, usuários ativos migram para hashes mais fortes sem reset forçado.
Após o lançamento, monitore login como qualquer endpoint crítico: latência de cauda (p95/p99), CPU e RAM em picos, picos de falhas de login e a velocidade com que hashes antigos são substituídos.
Próximos passos: lance com segurança e continue melhorando
Documente sua política e trate-a como algo vivo. Por exemplo: “Argon2id com X memória, Y iterações, Z paralelismo” ou “fator de custo bcrypt N”, mais a data em que escolheu e quando revisará (a cada 6 a 12 meses é um bom começo).
Mantenha um caminho de upgrade para não ficar preso a hashes antigos. Rehash-on-login é simples e funciona bem na maioria dos sistemas.
Um hash forte ajuda, mas não substitui controles contra abuso online. Limites de taxa, bloqueios e fluxos de redefinição de senha cuidadosos importam tanto quanto para a segurança no mundo real.
Se você constrói seu backend com uma plataforma visual como AppMaster, vale verificar se o módulo de autenticação usa hashing de senhas forte por padrão e se o custo de hashing é ajustado no mesmo tipo de infraestrutura onde você irá deployar. Esse pequeno teste inicial costuma ser a diferença entre “seguro e suave” e “seguro, mas inutilizável sob carga”.
FAQ
O hashing de senhas permite verificar um login sem armazenar a senha real. Você guarda um hash unidirecional e compara o hash da entrada do usuário com o valor armazenado; se o banco de dados vazar, atacantes ainda precisam adivinhar senhas em vez de lê-las.
A criptografia é reversível com uma chave, então se essa chave for roubada ou mal gerida, as senhas podem ser recuperadas. O hashing é projetado para ser unidirecional, então nem você consegue “descriptografar” o valor armazenado.
Hashes rápidos favorecem atacantes porque permitem testar palpites offline em altíssima velocidade, especialmente com GPUs. Hashes de senha devem ser intencionalmente lentos (e idealmente com uso de memória) para que adivinhações em grande escala fiquem caras.
Um salt é um valor único e aleatório armazenado junto com cada hash de senha. Ele evita que senhas idênticas gerem hashes idênticos e impede o reuso de tabelas pré-computadas, mas por si só não transforma senhas fracas em fortes.
Escolha Argon2id se sua stack o suportar bem e você puder ajustar memória de forma segura, pois ele foi pensado para resistir a cracking paralelo. Use bcrypt quando precisar de máxima compatibilidade e um modelo de ajuste mais simples; nesse caso, defina um fator de custo suficientemente alto.
O grande detalhe do bcrypt é o limite de 72 bytes: ele usa apenas os primeiros 72 bytes da senha e ignora o resto. Para evitar surpresas, deixe um limite claro de comprimento em bytes ou trate entradas longas de forma consistente.
A memória é o parâmetro mais importante porque limita quantos palpites um atacante pode executar em paralelo sem pagar caro por RAM e largura de banda. Memória demais também pode reduzir a capacidade do seu servidor de processar logins simultâneos, então ajuste para tráfego de pico, não só para testes isolados.
Busque um tempo de verificação previsível no hardware onde você realmente roda, frequentemente entre 100–300 ms por verificação, e então faça testes de carga para ver a concorrência. A configuração certa é a que se mantém responsiva durante picos de login e ainda encarece a adivinhação offline.
Armazene o algoritmo e seus parâmetros com o hash para que você possa verificar contas antigas e aumentar o custo depois. Uma abordagem comum é rehash-on-login: após um login bem-sucedido, se o hash armazenado for mais fraco que a política atual, recalcule com as novas configurações e salve.
Falhas comuns incluem ausência ou reuso de salts, lançar com custo baixo e nunca reavaliar, e superajustar memória do Argon2 até que logins estorem em picos. Também preste atenção ao tratamento de comprimento de senha (especialmente no bcrypt) e proteja o endpoint de login com limites de taxa e bloqueios curtos.


