Sempre use um algoritmo de hash de senha: Argon2 , scrypt , bcrypt ou PBKDF2 .
Argon2 venceu a competição de hash de senha de 2015. Scrypt , bcrypt e PBKDF2 são algoritmos mais antigos que são considerados menos preferidos agora, mas ainda são fundamentalmente sólidos, portanto, se sua plataforma ainda não suporta Argon2, não há problema em usar outro algoritmo por enquanto.
Nunca armazene uma senha diretamente em um banco de dados. Também não criptografe: caso contrário, se o site for violado, o invasor receberá a chave de descriptografia e poderá obter todas as senhas. As senhas devem ser hash .
Um hash de senha tem propriedades diferentes de um hash da tabela de hash ou de um hash criptográfico. Nunca use um hash criptográfico comum, como MD5, SHA-256 ou SHA-512 em uma senha. Um algoritmo de hash de senha usa um salt , que é único (não usado para nenhum outro usuário ou no banco de dados de ninguém). O salt é necessário para que os invasores não possam apenas pré-calcular os hashes de senhas comuns: com um salt, eles precisam reiniciar o cálculo para todas as contas. Um algoritmo de hash de senha é intrinsecamente lento - o mais lento possível. A lentidão prejudica muito mais o invasor do que você, porque o invasor precisa tentar muitas senhas diferentes. Para obter mais informações, consulte Como proteger senhas de hash com segurança .
Um hash de senha codifica quatro informações:
- Um indicador de qual algoritmo é usado. Isso é necessário para agilidade : as recomendações criptográficas mudam com o tempo. Você precisa poder fazer a transição para um novo algoritmo.
- Um indicador de dificuldade ou dureza. Quanto maior esse valor, mais computação é necessária para calcular o hash. Esse deve ser um valor de configuração constante ou global na função de alteração de senha, mas deve aumentar com o tempo à medida que os computadores ficam mais rápidos, portanto, é necessário lembrar o valor de cada conta. Alguns algoritmos têm um único valor numérico, outros possuem mais parâmetros (por exemplo, para ajustar o uso da CPU e o uso da RAM separadamente).
- O sal. Como o sal deve ser globalmente exclusivo, ele deve ser armazenado para cada conta. O sal deve ser gerado aleatoriamente em cada alteração de senha.
- O hash próprio, ou seja, a saída do cálculo matemático no algoritmo de hash.
Muitas bibliotecas incluem funções de par que empacotam convenientemente essas informações como uma única sequência: uma que aceita o indicador de algoritmo, o indicador de dureza e a senha, gera um sal aleatório e retorna a sequência completa de hash; e uma que usa uma senha e a cadeia de hash completa como entrada e retorna um booleano indicando se a senha estava correta. Não existe um padrão universal, mas uma codificação comum é
$ algoritmo $ parâmetros $ salt $ saída
onde algorithm
é um número ou uma sequência alfanumérica curta que codifica a escolha do algoritmo, parameters
é uma sequência imprimível salt
e output
é codificada em Base64 sem terminar=
.
16 bytes são suficientes para o sal e a saída. (Veja, por exemplo, recomendações para Argon2 .) Codificado em Base64, com 21 caracteres cada. As outras duas partes dependem do algoritmo e dos parâmetros, mas 20 a 40 caracteres são típicos. No total, são cerca de 82 caracteres ASCII ( CHAR(82)
e não há necessidade de Unicode), aos quais você deve adicionar uma margem de segurança se achar que será difícil ampliar o campo posteriormente.
Se você codificar o hash em um formato binário, poderá reduzi-lo a 1 byte para o algoritmo, 1 a 4 bytes para a dureza (se você codificar alguns dos parâmetros) e 16 bytes cada para o salt e a saída , para um total de 37 bytes. Diga 40 bytes (BINARY(40)
) para ter pelo menos alguns bytes sobressalentes. Observe que esses são bytes de 8 bits, caracteres não imprimíveis, em particular o campo pode incluir bytes nulos.
Observe que o comprimento do hash não tem nenhuma relação com o comprimento da senha.