Node.JS

Encriptar contraseñas con Node

En este post de programación con JavaScript del lado del servidor en el entorno de Node te mostraré cómo asegurar las contraseñas de los usuarios; esto es, encriptarlas.

De hecho me parece que el término correcto es hashear, pues encriptar es convertir algo plano a encriptado y luego poder hacer lo contrario; en cambio hashear es convertir algo plano a encriptado, pero ya no poder obtener el valor original a partir del encriptado.

Como sea, te mostraré cómo asegurar, encriptar o cifrar las contraseñas. Vamos a usar el algoritmo bcrypt pues es perfecto para hashear contraseñas en Node.

Instalando paquete

Al inicio de todo, yo iba a usar el paquete bcrypt, pero el mismo depende de alguna implementación en C / C++ y hay que compilarlo (o si hay suerte, se te descarga uno compilado) entonces es un poco complejo, así que me decidí por usar bcryptjs que está escrito en JavaScript puro.

No te preocupes, tiene la misma seguridad y es el mismo algoritmo, la única diferencia es que la implementación en C / C++ es más rápida al encriptar contraseñas, pero hablamos de milisegundos. En fin, tú entiendes.

Así que finalmente usamos bcyptjs y la instalamos con:

npm install bcryptjs

Luego debemos importarla en donde la vayamos a usar, con:

const bcrypt = require("bcryptjs");

Nota: recuerda que siempre puedes visitar la documentación, yo te mostraré con ejemplos pero siempre puedes investigar más sobre el tema.

Encriptando contraseña

Cifrar contraseñas con Node y bcrypt

Vamos a ver cómo encriptar una contraseña. Esta contraseña es la que tenemos que guardar en la base de datos; nunca debemos guardar la versión en texto plano.

Para hashear la contraseña invocamos a bcrypt.hash que recibe el texto plano, el número de rondas para la sal y un callback que se ejecutará cuando la contraseña haya sido hasheada.

// Importamos paquete
const bcrypt = require("bcryptjs");
// Primero vamos a hashear la contraseña
const palabraSecretaTextoPlano = "hunter2";
// Entre más rondas, mejor protección, pero más consumo de recursos. 10 está bien
const rondasDeSal = 10;

bcrypt.hash(palabraSecretaTextoPlano, rondasDeSal, (err, palabraSecretaEncriptada) => {
 if (err) {
  console.log("Error hasheando:", err);
 } else {
  console.log("Y hasheada es: " + palabraSecretaEncriptada);
 }
});

Las rondas son importantes. Entre mayor rondas sean, más seguro será el hash contra ataques de fuerza bruta, pero más tiempo tomará nuestro servidor para encriptar así que debemos encontrar un balance perfecto.

Con 10 rondas está bien, pero si quieres puedes hacer pruebas con más rondas. Me parece que el límite es 31 por el momento.

Comprobando contraseñas

Como lo dije, no hay manera de desencriptar, solo de comprobar que el texto plano que proporciona el usuario (al loguearse por ejemplo) coincide con el hash. Recuerda que este hash debe venir de tu base de datos.

Para comprobar si la contraseña que proporciona el usuario coincide con la que tenemos guardada en la base de datos, invocamos al método compare. Este método recibe la contraseña en texto plano, el hash y una función callback.

// Importamos paquete
const bcrypt = require("bcryptjs");
// Este hash debe venir de tu base de datos, por ejemplo
// Nota: yo sé que este hash es "hunter2", obviamente es para ejemplificar
const palabraSecretaHasheada = "$2a$10$P9yvh9ew5ZueNRjQGX4Eiui9jNhaKJCX24mRsrWSNvj.0O2FjNSB2";
const palabraSecretaProporcionadaPorUsuario = "hunter2";
// Recuerda. Los argumentos son: texto plano, encriptada, y callback
bcrypt.compare(palabraSecretaProporcionadaPorUsuario, palabraSecretaHasheada, (err, coinciden) => {
 if (err) {
  console.log("Error comprobando:", err);
 } else {
  console.log("¿La contraseña coincide?: " + coinciden);
 }
});

Recuerda que eres libre de cambiar los valores para probar si coincide o no con otros valores.

Un vistazo con async

Si a ti no te gustan los callbacks y sabes cómo usar async y await, aquí te muestro un ejemplo de cómo hacer para tener un código más limpio. Al encriptar (recuerda que es un ejemplo mío, los valores pueden venir de donde quieras):

// Primero vamos a hashear la contraseña
const palabraSecretaTextoPlano = "hunter2";
// Entre más rondas, mejor protección, pero más consumo de recursos. 10 está bien
const rondasDeSal = 10;
const palabraSecretaEncriptada = await bcrypt.hash(palabraSecretaTextoPlano, rondasDeSal);

Y al comprobar:

// Recuperamos la contraseña de la petición
const palabraSecretaTextoPlano = "hunter2";
// Y la guardada en la base de datos
const palabraSecretaEncriptada = "$2a$10$P9yvh9ew5ZueNRjQGX4Eiui9jNhaKJCX24mRsrWSNvj.0O2FjNSB2";
// Comprobamos...
const palabraSecretaValida = await bcrypt.compare(palabraSecretaTextoPlano, palabraSecretaEncriptada);

De este modo nos evitamos el “infierno de callbacks”, tenemos un código más ordenado y legible.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Entradas recientes

Servidor HTTP en Android con Flutter

El día de hoy te mostraré cómo crear un servidor HTTP (servidor web) en Android…

4 días hace

Imprimir automáticamente todos los PDF de una carpeta

En este post te voy a enseñar a designar una carpeta para imprimir todos los…

5 días hace

Guía para imprimir en plugin versión 1 desde Android

En este artículo te voy a enseñar la guía para imprimir en una impresora térmica…

1 semana hace

Añadir tasa de cambio en sistema de información

Hoy te voy a mostrar un ejemplo de programación para agregar un módulo de tasa…

2 semanas hace

Comprobar validez de licencia de plugin ESC POS

Los usuarios del plugin para impresoras térmicas pueden contratar licencias, y en ocasiones me han…

2 semanas hace

Imprimir euro € en impresora térmica

Hoy voy a enseñarte cómo imprimir el € en una impresora térmica. Vamos a ver…

4 semanas hace

Esta web usa cookies.