Node.js

Node

Tutorial Node: Introducción a la seguridad

Node.js: Aprende a proteger contraseñas y autenticar con JWT usando bcrypt y crypto. Mejora la seguridad de tus aplicaciones.

Aprende Node GRATIS y certifícate

Hash de contraseñas (bcrypt, crypto)

La confidencialidad de las contraseñas es crucial en cualquier aplicación que maneje usuarios. Para ello se recurre a algoritmos que transforman la contraseña original en un valor irreconocible, evitando almacenarlo en texto plano. En Node.js, se utilizan librerías como bcrypt o el módulo nativo crypto para realizar este proceso de forma sencilla y segura.

Con bcrypt, se genera un hash usando varios ciclos de encriptación (llamados salt rounds). La siguiente muestra demuestra un uso asíncrono que crea un hash a partir de una contraseña en texto plano:

import { hash } from "bcrypt";

const plainTextPassword = "MySecurePassword";
const numberOfRounds = 10;

try {
    const passwordHashed = await hash(plainTextPassword, numberOfRounds);
    console.log("Hash created:", passwordHashed);
} catch (error) {
    console.log("Error generating hash:", error);
}

Para verificar la contraseña, se compara el texto ingresado con el hash almacenado, sin necesidad de administrar la sal manualmente:

try {
    const isValid = await compare(plainTextPassword, passwordHashed);
    console.log("Is password valid?", isValid);
} catch (error) {
    console.log("Error comparing password:", error);
}

El módulo nativo crypto proporciona métodos como pbkdf2 que también se usan para encriptar valores sensibles. Este método aplica iteraciones y sal para evitar ataques de fuerza bruta:

import { randomBytes, pbkdf2 } from "crypto";
import { promisify } from "util";
const pbkdf2Async = promisify(pbkdf2);

const contraseña = "OtraContraseña123";
const salAleatoria = randomBytes(16).toString("hex");
const iteraciones = 10000;
const longitudClave = 64;
const algoritmo = "sha512";

try {
    const derivedKey = await pbkdf2Async(contraseña, salAleatoria, iteraciones, longitudClave, algoritmo);
    console.log("Clave derivada hex:", derivedKey.toString("hex"));
} catch (error) {
    console.log("Error al generar la clave derivada:", error);
}

La robustez de los hashes depende tanto del algoritmo como del manejo adecuado de la sal. Usar buenas prácticas como establecer las iteraciones recomendadas y almacenar correctamente la sal, refuerza la seguridad de este método y protege la integridad de la información.

Nota: Estamos utilizando promisify para convertir funciones basadas en callbacks en funciones que devuelven promesas.

Tokens JWT (implementación manual con librerías jsonwebtoken)

La autenticación mediante tokens JWT permite gestionar sesiones sin necesidad de almacenar información en el servidor. Cada token contiene datos codificados en Base64 junto con una firma que garantiza la integridad de la información.

Un token JWT habitualmente incluye un payload con el identificador del usuario, la expiración y otros campos como el rol. Esta estructura lo hace especialmente útil para mantener la coherencia de credenciales en aplicaciones distribuidas.

Para implementar un token JWT con la librería jsonwebtoken, se prepara un objeto payload y se define una clave secreta. El siguiente fragmento de código muestra cómo generar un token:

import jwt from "jsonwebtoken";

const secretKey = "my-secret-key";
const payload = { userId: 42, role: "editor" };
const options = { expiresIn: "2h" };

const generatedToken = jwt.sign(payload, secretKey, options);
console.log("Token created:", generatedToken);

La verificación del token se realiza con la misma clave. Si el token ha caducado o ha sido manipulado, se generará un error:

jwt.verify(generatedToken, secretKey, (error, decoded) => {
    if (error) {
        console.error("Invalid token:", error);
        return;
    }
    console.log("Decoded payload:", decoded);
});

Entre las buenas prácticas se incluyen:

  • Rotar la clave secreta periódicamente.
  • Definir una expiración adecuada para cada tipo de token.
  • Restringir el payload a la información estrictamente necesaria.

Estas directrices ayudan a mantener la seguridad del sistema y reducen la probabilidad de uso indebido del token en entornos de producción.

Para seguir leyendo hazte Plus

¿Ya eres Plus? Accede a la app

Plan mensual

19.00 € /mes

Precio normal mensual: 19 €
47 % DE DESCUENTO

Plan anual

10.00 € /mes

Ahorras 108 € al año
Precio normal anual: 120 €
Aprende Node GRATIS online

Todas las lecciones de Node

Accede a todas las lecciones de Node y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Accede GRATIS a Node y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  • Utilizar bcrypt para hashear contraseñas de forma segura.
  • Implementar verificación de contraseñas con bcrypt.
  • Aplicar el módulo crypto para encriptar información confidencial.
  • Gestionar autenticación con JWT con jsonwebtoken.
  • Entender la importancia de la rotación de claves y expiación en tokens.
  • Adoptar buenas prácticas criptográficas para proteger información sensible.