MiServe DevTools

Os seus autocolantes

Fixe aqui as ferramentas. Ficam guardadas neste navegador.

Gerador e verificador de hashes bcrypt

Calcule o hash bcrypt de uma palavra-passe com o custo que escolher, verifique uma palavra-passe contra um hash e veja as partes de um hash.

Calcular o hash de uma palavra-passe

Custo 10 significa 1.024 iterações de expansão da chave. Cada nível a mais duplica o trabalho, para si e para quem tentar adivinhar.

Hash bcrypt

Verificar uma palavra-passe contra um hash

Resultado

Funciona no seu navegador com WebAssembly. Nada do que cola é enviado.

Sobre esta ferramenta

Porque é que o bcrypt é lento de propósito

As bases de dados de palavras-passe são roubadas, e quem tem uma pode tentar adivinhar palavras-passe offline, tão depressa quanto o seu hardware permitir. Os hashes de uso geral, como o SHA-256, são feitos para ser rápidos, por isso uma única placa gráfica testa milhares de milhões de candidatas por segundo. O bcrypt, publicado por Niels Provos e David Mazières em 1999, assenta na dispendiosa expansão de chave da cifra Blowfish e repete-a um número configurável de vezes, o que torna cada tentativa cara.

Cada hash tem também o seu próprio sal aleatório de 16 bytes. Dois utilizadores com a mesma palavra-passe obtêm hashes diferentes, e uma tabela calculada antecipadamente para um sal não serve para o seguinte. Um hash bcrypt não pode ser decifrado. O ataque prático é adivinhar, por isso uma palavra-passe fraca continua a cair depressa, seja qual for o custo.

O que significa o custo e como escolhê-lo

O custo é o logaritmo de base 2 do número de iterações de expansão da chave: o custo 10 corresponde a 1024 iterações e o custo 12 a 4096. Somar um duplica o tempo de cada início de sessão e de cada tentativa de um atacante. O custo fica escrito no hash, por isso pode aumentá-lo mais tarde: os hashes antigos continuam a ser verificados, e pode recalcular o hash de uma palavra-passe com o novo custo da próxima vez que o seu dono iniciar sessão.

Escolha o custo mais alto que o seu servidor consiga suportar num início de sessão, e nunca menos de 10, que é o mínimo que a OWASP Password Storage Cheat Sheet indica para o bcrypt. O tempo mostrado aqui é medido em WebAssembly no seu navegador, que costuma ser mais lento do que código nativo num servidor, por isso meça na máquina que vai calcular os hashes. É por essa razão que esta ferramenta não passa do custo 14.

O limite de 72 bytes

O bcrypt usa no máximo 72 bytes da palavra-passe. O limite é em bytes, não em caracteres: em UTF-8, uma letra acentuada como é ocupa dois bytes, a maioria dos caracteres CJK três e a maioria dos emojis quatro ou mais. Muitas bibliotecas cortam as entradas mais longas sem avisar, o que significa que duas palavras-passe longas com os mesmos primeiros 72 bytes são aceites pelo mesmo hash. A implementação em Go usada aqui recusa calcular o hash de entradas mais longas, e esta ferramenta avisa quando isso acontece.

Se os seus utilizadores puderem escolher palavras-passe mais longas, a solução simples é rejeitá-las no registo com uma mensagem clara. Uma alternativa comum calcula primeiro o hash da palavra-passe com SHA-256 e passa ao bcrypt o texto Base64 ou hex desse resumo. Nunca deve passar os bytes em bruto do resumo, porque algumas implementações param de ler num byte zero, e a cheat sheet da OWASP desaconselha este tipo de pré-hashing, porque abre caminho a um ataque chamado password shucking. Para um sistema novo, a OWASP recomenda o Argon2id em vez do bcrypt, e o Argon2id não tem o limite de 72 bytes.

Ler um hash, e como esta ferramenta funciona

Um hash bcrypt tem 60 caracteres: um prefixo de versão como $2b$, um custo de dois dígitos e $, 22 caracteres de sal e 31 caracteres de resumo, ambos no alfabeto Base64 próprio do bcrypt (./A-Za-z0-9). Tudo o que é preciso para verificar uma palavra-passe está nessa única string, por isso não há uma coluna à parte para guardar o sal.

O cálculo e a verificação são feitos pelo pacote golang.org/x/crypto/bcrypt do Go, compilado para WebAssembly e executado numa thread em segundo plano do seu navegador. As palavras-passe e os hashes não são enviados para lado nenhum nem guardados. A página destina-se a dados de teste, fixtures e à verificação de um hash que já tem: o hash das palavras-passe de utilizadores reais deve ser calculado pela sua aplicação, no seu servidor.

Perguntas

Porque é que obtenho um hash diferente de cada vez para a mesma palavra-passe?

Cada hash é criado com um novo sal aleatório, e o sal faz parte do resultado. Para verificar uma palavra-passe, o bcrypt lê o sal e o custo do hash guardado e repete o cálculo. É por isso que se compara com uma função de verificação e nunca calculando o hash outra vez e comparando strings.

Que custo de bcrypt devo usar?

Use pelo menos 10, e suba enquanto um início de sessão no seu servidor terminar num tempo que considere aceitável. Cada nível duplica o tempo, por isso meça no hardware de produção. Reveja o valor de poucos em poucos anos, à medida que o hardware fica mais rápido.

Qual é a diferença entre $2a$, $2b$ e $2y$?

Marcam revisões feitas depois de erros em implementações específicas: o $2y$ vem de uma correção de 2011 no crypt_blowfish, o código que o PHP usa, e o $2b$ de uma correção de 2014 no OpenBSD. Para palavras-passe até 72 bytes, os três produzem o mesmo resumo. Esta ferramenta escreve $2a$ e verifica os três.

A palavra-passe que escrevo é enviada para um servidor?

Não. O hash é calculado no seu dispositivo por um módulo WebAssembly, e a ferramenta não faz nenhum pedido de rede com o que escreve. Nada fica guardado entre visitas.

Mais ferramentas de Hash