Como criptografar senhas com nodejs e bcryptjs

Como criptografar senhas com nodejs e bcryptjs

Para um desenvolvimento seguro é muito importante que tratemos dados sensíveis com muito cuidado e segurança. Neste tutorial você aprenderá a criptografar senhas no nodejs com bcryptjs.

Programação
09/04/2023

Introdução

A criptografia de senhas no backend é um passo importante no desenvolvimento de software e isso independe da tecnologia que estiver usando. Com ela nós podemos mascarar as senhas do usuário para que fiquem difíceis de adivinhar ou decodificar.

Neste tutorial vamos utilizar a biblioteca bcryptjs, uma otimização bcrypt em Javascript com zero dependências.

Como funciona o bcrypt

O bcrypt é uma biblioteca com funções utilitárias responsáveis por aplicar algoritmos de criptografia em strings, como senhas. Fornece uma ótima camada de segurança que protege de ataques como o brute-force. Ela é adaptativa ao longo do tempo e pode ir reforçando sua segurança aumentando a contagem de iterações.

Além disso, ela implementa um sistema de salts, salt em criptografia refere-se a um dado aleatório que é usado para adicionar mais segurança no hash ao ser armazenado, por exemplo, no banco de dados.

Com salts é possível se proteger contra ataques rainbow table, como também resolver problemas de duplicidade de senhas e senhas comuns, pois nesses casos o hash gerado seria igual também, mas com o salt eles serão diferentes mesmo que as strings que serão criptografadas sejam iguais.

Os salts são gerados aleatoriamente e geralmente concatenados com o hash gerado, nunca a senha original.

Criptografando uma senha em nodejs com bcryptjs

Pronto, agora que entendemos um pouco sobre o bcrypt, vamos ver como usar ele no Javascript.

Criando a estrutura

Antes de começar precisamos iniciar a estrutura e instalar a biblioteca. Na pasta em que você criará o projeto execute o seguinte comando no terminal:

1npm init -y

Esse comando irá iniciar um arquivo package.json com informações do seu projeto. Depois execute o seguinte comando para instalar a biblioteca:

1npm install bcryptjs

Pronto, agora crie um arquivo index.js dentro da pasta.

Criptografar senhas

Agora dentro do arquivo index.js você colocará:

1const bcrypt = require("bcryptjs"); 2const password = "tutorialdecriptografia123"; 3const salts = 10;

Primeiro estamos pegando a biblioteca bcrypt com o require, depois criamos a senha e, por último, definimos o número de salts.

Quanto maior o salt mais difícil se torna para ataques de brute-force, porém o valor é diretamente proporcional ao custo em utilização da CPU. Então, quanto maior, mais recursos serão utilizados.

Função para criar o hash e criptografar a senha

Essa é a função que gera o hash:

1async function hashingPassword(password, saltRounds) { 2 try { 3 const hashedPassword = await bcrypt.hash(password, saltRounds); 4 console.log(hashedPassword); 5 } catch (error) { 6 console.log(error); 7 } 8}

Nesse tutorial utilizaremos o método assíncrono porém também é possível usar o bcrypt sincronicamente.

Então criamos uma função assíncrona que recebe dois parâmetros: a senha que será criptografada e o valor de salts. Dentro do try usamos o método hash do bcrypt para gerar o hash da senha, esse método recebe como parâmetros os mesmos da função.

Observação para relembrar: parâmetro é o que a função recebe, argumento é o que é passado para ela.

Por fim, damos console.log() no resultado.

Comparando o hash com a senha

Agora criaremos uma função que será responsável por comparar o hash gerado com a senha original.

1async function comparePassword(password, hash) { 2 try { 3 const responseCompare = await bcrypt.compare(password, hash); 4 console.log(responseCompare); 5 } catch (error) { 6 console.log(error); 7 } 8}

Essa função recebe como parâmetros a senha original e o hash gerado. Dentro do try usamos o método compare do bcrypt que faz a comparação e retorna true se o hash pertence a senha original ou false se não, o método recebe a senha e o hash como parâmetros.

Em seguida damos um console.log() no resultado.

Resultados

Primeiro chamamos a função que irá gerar o hash passando os argumentos:

1hashingPassword(password, salts);

Aqui o resultado gerado foi o seguinte:

1// $2a$10$2dubcdUP/in4MFai840Ifebl2ciYUa0ZmnLkeLDNaFGnSSSD.c17e

Esse é o hash criptografado gerado a partir da senha “tutorialdecriptografia123” que criei lá no topo. Mas lembre-se: mesmo você usando a mesma senha que usei, o hash gerado será diferente devido ao sistema de salts. Tente executar novamente a função, você verá que o resultado será diferente, assim ocorre a cada execução.

Agora comparemos:

1comparePassword(password, "$2a$10$2dubcdUP/in4MFai840Ifebl2ciYUa0ZmnLkeLDNaFGnSSSD.c17e");

Estou chamando a função de comparação e passando como argumentos a senha e o hash gerado, o resultado que obtive com essa operação foi true, ou seja, ele identificou que aquele hash foi gerado daquela senha, em uma aplicação de login isso significaria que o usuário digitou a senha corretamente.

Se você tentar mudar por exemplo a senha:

1comparePassword(“ihrapaz”, "$2a$10$2dubcdUP/in4MFai840Ifebl2ciYUa0ZmnLkeLDNaFGnSSSD.c17e");

A resposta será false, assim também seria mudando um caractere do hash.

Conclusão

Vimos uma das maneiras de fazer a criptografia de strings, lembrando que tem vários outros métodos disponíveis no mercado, tanto com bcrypt quanto com outras ferramentas.

Agora você pode usar a mesma lógica para, por exemplo, salvar senhas de usuários em banco de dados com mais segurança. Basta você salvar no banco o hash invés da senha original.

Segurança é um tripé importante na criação de uma aplicação e devemos empregar o máximo de energia possível nessa etapa.