Conociendo la librería Bcrypt
La seguridad es sin duda la mayor preocupación cuando se trata de datos, información sensible como credenciales de acceso, datos privados y confidenciales. En un mundo totalmente conectado y disponible como los días actuales, donde los sistemas están en línea casi el 99% del tiempo, proteger la información y los datos que circulan por la red es la principal misión de los desarrolladores, junto con el rendimiento de la aplicación.
Entre las muchas opciones de seguridad disponibles hoy, la biblioteca Bcrypt se destaca, creada por Niels Provo y David Mazières, criptógrafos e investigadores que crearon un sistema de criptografía que utiliza un hash de contraseñas. Este algoritmo es uno de los más seguros en la actualidad, ya que permite agregar un código aleatorio al hash original, también permite aumentar la dificultad de descifrar el hash al agregar un salt. Permitindo utilizar el poder computacional para cifrar los datos.
Al agregar códigos al hash original, evita ataques de fuerza bruta y ataques que intenten revertir la criptografía del hash, utilizando tablas rainbow.
Utilizado para proteger los sistemas de contraseñas de OpenBSD, además de distribuciones linux como SUSE Linux, implementado en los principales lenguajes de programación, también está disponible para JavaScript, y en este artículo veremos su uso con NodeJS. Aunque este mecanismo de cifrado comúnmente utiliza 56 caracteres o bytes, puede llegar hasta 72 bytes.
Este sistema es el más recomendado para almacenar datos sensibles en bases de datos, como contraseñas, CPF, RG o ID interno de la empresa, ya que en caso de que los datos sean expuestos, el invasor no podrá revertir a los datos en texto limpio, incluso usando rainbow tables.
Cómo funciona la librería BcryptJS
Con Node.JS es posible utilizar la librería bcrypt usando el módulo de terceros bcrypt. con alrededor de 500.000 descargas de la biblioteca en el repositorio NPM, la librería bcrypt se encuentra entre las más populares en el gestor de paquetes NPM.
Para Node.JS versión 12.13 usamos la versión 3.0.6 o superior de la librería bcrypt.
npm i bcrypt
En el siguiente ejemplo aplicaremos la biblioteca bcrypt en un hash de contraseñas dentro de un bucle for, que encriptará la contraseña utilizando salts que van de 10 a 20. Al ejecutar el script en Node.JS, nota que hasta 14 la visualización es casi instantánea, dependiendo de la máquina que utilices, puede que de 15 a 20 tarde un poco en generar la criptografía.
const bcrypt = require('bcrypt');
const pass = '!]m:#$xDY@p/QDeW';
//examinando el hash de 2^10 hasta 2^20
for (let saltRounds = 10; saltRounds <= 15; saltRounds++) {
bcrypt.hash(pass, saltRounds)
.then((passHashed)=> {
console.time(`Time: ${saltRounds}`);
console.log(passHashed);
console.timeEnd(`Time: ${saltRounds}`);
});
}
Este tiempo adicional es útil para impedir ataques de fuerza bruta, se recomienda que utilices hasta 240 ms, más de eso podría consumir mucho poder computacional. En un notebook Dell Inspiron i7 con 8GB de RAM y Windows 10.
El resultado se presentó a continuación, ten en cuenta que en esta máquina el salt 12 sería el ideal por estar hasta 240ms. puedes ejecutar este script en tu servidor, no necesariamente hasta 20, con esto tendrás una idea de qué Salt deberías utilizar. Salt tiene que ver con sal de comida, con el condimento que pones en la comida. Añades la cantidad de "condimento" ideal para ejecutar tu script.
Presta atención a la cantidad de milisegundos que la criptografía genera, hasta 240ms está excelente.
Nota que en este caso el número de Salt está claramente en el hash, ocupa la posición 5 y 6 del hash comenzando a contar desde $. Si no deseas mostrar el número de Salt en texto limpio, es posible generar el Salt con el método bcrypt.genSalt, así el número no quedará expuesto.
Comparando la información
Podemos utilizar el método bcrypt.compare() para comparar la contraseña o datos suministrados con lo que ya tenemos almacenado en una base de datos, por ejemplo. Así el método compare cifrará la contraseña proporcionada y la comparará con la contraseña cifrada. Es posible utilizar async y await para realizar esta comparación.
En el mismo archivo agregaremos a continuación el método compare. salt.js
.
.
.
//informado en el formulario
let userPass = '!]m:#$xDY@p/QDeW'
async function check(username, pass){
//buscando en la base de datos la contraseña del usuario
let passHashedDB = '$2b$12$dbstSfo1FN9jnZOSQ96N7eMMMe9FFI2QmYWo6E44WhutEUg9kZOcW'
const match = await bcrypt.compare(pass, passHashedDB )
if(match) {
console.log('¡Otorgado!')
}else {
console.log('Acceso Denegado')
}
}
//llamando a la función check
check('JediMaster',userPass)
Nota que al ejecutar el script nuevamente, al llegar al Salt 12 muestra ¡Otorgado!, es decir, está correcto. En el ejemplo, la variable userPass corresponde a lo que un usuario proporcionó en un formulario en el front-end y fue enviado por medio de la solicitud. La variable passHashedDB es una consulta que se haría en una Base de Datos MySQL, MongoDB u otros, con la contraseña cifrada. Recomendamos siempre utilizar la versión asíncrona de los métodos de la librería bcrypt, esto hará que el servidor utilice el EventLoop de Node y hilos de procesadores asíncronos, aumentando el rendimiento de la aplicación.
Comparando la contraseña proporcionada con la contraseña cifrada, después del Salt 12: ¡Otorgado!
Entonces eso es todo, hoy hablamos un poco sobre la librería bcrypt, si deseas aprender más sobre esta y otras librerías, no dudes en consultar nuestro Curso Completo de NodeJS donde enseñamos de forma profesional los recursos de Node, así como consejos valiosos como estos.
Para descargar el código utilizado en este tutorial accede a: https://github.com/hcodebr/bcrypt-tutorial
¡Nos vemos en un próximo artículo!
Glaucio Daniel