@mp-front/encrypter
v0.0.1
Published
Biblioteca de encriptación/desencriptación basada en JWE (JSON Web Encryption) para el ecosistema `@mp-front`. Usa el algoritmo A256KW + A256GCM para proteger datos sensibles y SHA-256 para generar hashes.
Downloads
139
Readme
@mp-front/encrypter
Biblioteca de encriptación/desencriptación basada en JWE (JSON Web Encryption) para el ecosistema @mp-front. Usa el algoritmo A256KW + A256GCM para proteger datos sensibles y SHA-256 para generar hashes.
Tabla de Contenidos
Sección 1: Configuración
Paso 1: Instalar dependencias
Desde la raíz del monorepo:
npm installSi necesitas usar el encrypter desde otro paquete del monorepo:
npm install @mp-front/encrypter --workspace=packages/tu-paquetePeer dependencies requeridas (deben estar instaladas en tu proyecto):
| Paquete | Versión |
| ------------------ | ------- |
| jose | 6.2.2 |
| @mp-front/logger | 0.0.1 |
Paso 2: Variables de entorno
Crea o edita tu archivo .env con estas variables (requeridas por @mp-front/logger, peer dependency):
# Variables requeridas por @mp-front/logger (peer dependency)
NEXT_PUBLIC_APP_LOGS_NAME=mi-aplicacion
NEXT_PUBLIC_LOGS_LEVEL=info
NEXT_PUBLIC_SILENT_LOGS=falseNota sobre la clave secreta:
- La clave de encriptación se pasa directamente al constructor de
Encrypter— no es una variable de entorno del paquete. - Tú decides de dónde obtenerla (env var, secrets manager, config, etc.).
- Debe tener al menos 32 caracteres para el algoritmo A256KW.
- Nunca la expongas en el frontend ni la subas a git.
Paso 3: Importar el Encrypter
import { Encrypter } from "@mp-front/encrypter"
// Crea una instancia pasando tu clave secreta (de donde tú la obtengas)
const encrypter = new Encrypter(process.env.MY_SECRET_KEY)
// Listo para usar
const encrypted = await encrypter.encrypt({ userId: "123" })Sección 2: Uso
Eventos de disparo único (Single Shot)
Estos son operaciones que se ejecutan una sola vez en respuesta a un evento específico.
Ejemplo: Encriptar datos antes de guardar en cache
import { Encrypter } from "@mp-front/encrypter"
const encrypter = new Encrypter(process.env.MY_SECRET_KEY)
async function saveUserSession(userId: string, sessionData: object) {
// Encriptar datos sensibles antes de guardarlos
const encrypted = await encrypter.encrypt(sessionData)
// Guardar el string encriptado en Redis/cache
await redis.set(`session:${userId}`, encrypted, "EX", 3600)
}Ejemplo: Desencriptar datos al leer de cache
import { Encrypter } from "@mp-front/encrypter"
const encrypter = new Encrypter(process.env.MY_SECRET_KEY)
async function getUserSession(userId: string) {
const cached = await redis.get(`session:${userId}`)
if (!cached) return null
// Verificar si está encriptado antes de desencriptar
const isEncrypted = await encrypter.isEncrypted(cached)
if (isEncrypted) {
return await encrypter.decrypt<SessionData>(cached)
}
// Si no está encriptado, parsear directamente
return JSON.parse(cached)
}Ejemplo: Generar un hash SHA-256 para identificadores
import { Encrypter } from "@mp-front/encrypter"
const encrypter = new Encrypter(process.env.MY_SECRET_KEY)
function generateCacheKey(prefix: string, identifier: string): string {
// Genera un hash determinístico del identificador
const sha = encrypter.generateSHA(identifier)
return `${prefix}:${sha}`
}
// Uso
const key = generateCacheKey("user", "[email protected]")
// Resultado: "user:a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e"Eventos recurrentes
Estos son operaciones que se ejecutan repetidamente como parte de un flujo continuo.
Ejemplo: Middleware que encripta respuestas sensibles
import { Encrypter } from "@mp-front/encrypter"
const encrypter = new Encrypter(process.env.MY_SECRET_KEY)
// Se ejecuta en cada response que contiene datos sensibles
async function encryptResponseMiddleware(req, res, next) {
const originalJson = res.json.bind(res)
res.json = async data => {
if (data.sensitive) {
data.payload = await encrypter.encrypt(data.payload)
delete data.sensitive
}
return originalJson(data)
}
next()
}Ejemplo: Procesador de cola que encripta/desencripta mensajes
import { Encrypter } from "@mp-front/encrypter"
const encrypter = new Encrypter(process.env.MY_SECRET_KEY)
// Se ejecuta por cada mensaje en la cola
async function processMessage(message: QueueMessage) {
// Desencriptar el payload del mensaje
const payload = await encrypter.decrypt<OrderData>(message.body)
// Procesar...
await processOrder(payload)
// Encriptar resultado antes de enviar a otra cola
const result = await encrypter.encrypt({
orderId: payload.id,
status: "processed",
})
await outputQueue.send(result)
}Ejemplo: Job programado que rota datos encriptados
import { Encrypter } from "@mp-front/encrypter"
const encrypter = new Encrypter(process.env.MY_SECRET_KEY)
// Se ejecuta periódicamente para verificar integridad
async function verifyEncryptedData(keys: string[]) {
for (const key of keys) {
const value = await redis.get(key)
const isValid = await encrypter.isEncrypted(value)
if (!isValid) {
console.warn(`Key ${key} contains unencrypted data, re-encrypting...`)
const parsed = JSON.parse(value ?? "{}")
const encrypted = await encrypter.encrypt(parsed)
await redis.set(key, encrypted)
}
}
}Ejemplo: Listener de eventos que hashea identificadores
import { Encrypter } from "@mp-front/encrypter"
const encrypter = new Encrypter(process.env.MY_SECRET_KEY)
// Se ejecuta en cada evento de usuario
eventBus.on("user:action", async event => {
// Generar key hasheada para el rate limiter
const rateLimitKey = `ratelimit:${encrypter.generateSHA(event.userId)}`
const count = await redis.incr(rateLimitKey)
if (count === 1) {
await redis.expire(rateLimitKey, 60)
}
if (count > 100) {
throw new Error("Rate limit exceeded")
}
})Referencia Rápida de Métodos
| Método | Retorno | Descripción |
| ----------------------- | ------------------ | ------------------------------------------- |
| encrypt<T>(payload) | Promise<string> | Encripta cualquier valor serializable a JWE |
| decrypt<T>(encrypted) | Promise<T> | Desencripta un string JWE al tipo original |
| isEncrypted(value) | Promise<boolean> | Verifica si un string es un JWE válido |
| generateSHA<T>(value) | string | Genera hash SHA-256 hex de cualquier valor |
Tips
- Misma clave en todos los servicios: Si encriptas en un servicio y desencriptas en otro, ambos deben pasar la misma clave al constructor.
- No encriptes datos grandes: JWE agrega overhead. Para archivos grandes, usa encriptación a nivel de storage.
generateSHAes determinístico: El mismo input siempre produce el mismo hash. Útil para cache keys.isEncryptedintenta desencriptar: Tiene costo de CPU. No lo uses en loops de alto rendimiento.
