Esta tradução foi gerada automaticamente e está pendente de revisão.
Em aplicações que controlam a autenticação de usuários, armazenar senhas em texto puro não deve ser uma opção. Você é responsável por garantir a segurança desses dados, por isso deve sempre criptografar todas as senhas e nunca armazenar as senhas em texto puro. Neste artigo vamos aprender como criptografar senhas utilizando a técnica de sal. Usarei exemplos em JavaScript puro e ES5.
O que é a técnica do sal?
A técnica do sal (salt em inglês) consiste em pegar a senha do usuário e criptografá-la junto com um conjunto de texto aleatório único, armazenando o resultado no banco, tanto a senha criptografada quanto o texto utilizado como sal.
Por que usar a técnica do sal?
A criptografia de uma senha é sempre a mesma para aquela senha, e ainda que a criptografia seja unidirecional, e não possa ser descriptografada, existem tabelas que armazenam esse texto criptografado e o texto de referência original, o que facilita para um hacker chegar a esse hash. Ao adicionar um sal único a cada senha, garantimos que o resultado gerado a partir da criptografia seja único, dificultando sua identificação.
E a técnica de sal e pimenta?
Existem outras técnicas para armazenar senhas de forma segura. Uma variante do sal é o sal e pimenta, que consiste em armazenar o sal único por usuário e combiná-lo com a pimenta (pepper), que é basicamente uma chave no texto gerada a nível de aplicação e compartilhada por todas as senhas. Muitos argumentam que ter essa camada de segurança a nível de aplicação evita que possíveis falhas de acesso ao seu banco comprometam as senhas, já que os atacantes também teriam acesso ao sal. O problema dessa técnica é a manutenção, pois é necessário armazenar de forma segura esse texto, e em caso de qualquer brecha com a pimenta todas as senhas se tornarão inválidas.
Etapas do processo
Em resumo, a prática dessa técnica será:
Criação e armazenamento de senhas
- Receber a senha do usuário
- Gerar um sal (texto aleatório)
- Combinar o sal com a senha
- Criptografar a combinação de senha e sal
- Salvaremos o resultado da senha e também o sal utilizado
Validação de senha
- Validar o e-mail (identificador do usuário) e obter o sal no banco de dados
- Combinar o sal com a senha que for digitada
- Criptografar a combinação da senha digitada e o sal
- Comparar esse hash com o hash salvo no banco
Neste artigo não cobriremos o processo completo. Para a parte de criptografia usaremos a biblioteca Cripto nativa e para a parte do banco simularemos com o console.log.
Vamos ao código
Primeiro precisamos importar o módulo cripto
var crypto = require('crypto');
Função para gerar o Sal
Para gerar o sal vamos utilizar uma função do próprio módulo cripto que já gera uma string aleatória; vamos utilizar uma string com 16 caracteres como nosso sal.
var generateSalt = function (length) {
return crypto.randomBytes(Math.ceil(length / 2))
.toString('hex')
.slice(0, length);
};
Função para criptografar a senha com o sal
Agora faremos a função responsável por unir um sal e uma senha, retornando um objeto com o hash criptografado gerado e o sal. Usaremos o algoritmo de criptografia sha512.
var sha512 = function (password, salt) {
var hash = crypto.createHmac('sha512', salt); // Algoritmo Crypto sha512
hash.update(password);
var value = hash.digest('hex');
return {
salt: salt,
hash: value
};
};
Função para gerar um novo hash de senha
Vamos criar agora uma função que gera uma nova senha para o usuário, que pode ser usada no registro ou na atualização de senha.
function saltHashPassword(userpassword) {
var salt = generateSalt(16); // Vamos gerar o sal
var passwordData = sha512(userpassword, salt); // Pegamos a senha e o sal
// A partir daqui é possível retornar a senha ou salvar no banco o sal e a senha
console.log('Hash password: ' + passwordData.hash);
console.log('Salt: ' + passwordData.salt);
}
saltHashPassword('123456');
saltHashPassword('ABC123');
Validar senha (login)
Agora que salvamos um hash de senha e sal no banco, precisamos de uma função para autenticar esse usuário em nossa aplicação:
function login(passwordEntered, salt, hash) {
var passwordData = sha512(passwordEntered, salt);
return hash === passwordData.hash;
}
Conclusão
Aprendemos o processo de gerar uma senha e criptografá-la de forma segura para armazenar em nosso banco. As funções são apenas exemplos básicos da técnica; recomendo que você as melhore e adapte ao seu cenário.