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.
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.
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.
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.
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.
El día de hoy te mostraré cómo crear un servidor HTTP (servidor web) en Android…
En este post te voy a enseñar a designar una carpeta para imprimir todos los…
En este artículo te voy a enseñar la guía para imprimir en una impresora térmica…
Hoy te voy a mostrar un ejemplo de programación para agregar un módulo de tasa…
Los usuarios del plugin para impresoras térmicas pueden contratar licencias, y en ocasiones me han…
Hoy voy a enseñarte cómo imprimir el € en una impresora térmica. Vamos a ver…
Esta web usa cookies.