LUCipher
~/lucipher — let us cipher

pet-project · criptografía · aprendizaje

LUCipher

Un experimento personal de cifrado que empezó en 2019 jugando con "ruido", y siete años después se rehízo desde cero como una librería de cifrado autenticado que corre igual en Node y en el navegador.

$ npm i lucipher Ver en npm ↗ Código ↗
v4.0.1 · estable AES-256-GCM + PBKDF2 Node + navegador 0 dependencias Apache-2.0

cat IDEA.md

## La idea

La pregunta original era ingenua y honesta: si ciframos siempre el mismo texto con la misma clave, la salida es siempre idéntica… ¿cómo hacemos que cambie?

La primera respuesta fue divertida: añadir ruido pseudoaleatorio al texto antes de cifrarlo (con un paquetito propio, wordsnoise) y quitarlo al descifrar. Así, cada cifrado salía distinto. Funcionaba… como juguete.

Años después, un análisis a fondo destapó la verdad: el ruido no aportaba seguridad, solo parcheaba un problema autoinfligido —un IV fijo— y encima corrompía textos con ciertos caracteres. Ese hallazgo fue el punto de partida del rediseño.

git log --oneline --reverse

## Cómo evolucionó

v1 · la idea2019experimento

Nace como pet-project

Un experimento para aprender: cifrar texto y hacer que la salida variara con "ruido". La semilla de todo, sin pretensiones.

v2.x2019 – 2023inseguro

AES-128-CBC + ruido, publicado en npm

Cifraba y descifraba, sí, pero con fallos serios: IV fijo hardcodeado, sin integridad (maleable), secretos de relleno escritos en el propio código y un ruido que borraba caracteres legítimos como € ½ µ. Servía para ocultar de una mirada casual, no para proteger nada.

análisisjul 2026con IA

Una revisión crítica y honesta

Un análisis objetivo —asistido por IA— puso nombre a cada defecto y, sobre todo, distinguió la buena intención (salida variable) de la mala implementación (ruido sobre un IV fijo). De ahí salió el plan de rediseño.

v3.0jul 2026AEAD

Cifrado autenticado de verdad

ChaCha20-Poly1305 + scrypt, salt y nonce aleatorios por mensaje (adiós al ruido), integridad real (un texto manipulado se detecta) y cero secretos en el fuente. El bug de pérdida de datos, resuelto.

v4.0jul 2026isomorfo

El mismo cifrado en Node y en el navegador

Reescrito sobre la Web Crypto API: AES-256-GCM + PBKDF2. Un único código que corre en ambos entornos, con textos interoperables entre ellos —cifra en el servidor, descifra en el cliente— y verificado con un test real de navegador. El precio consciente: PBKDF2 en vez de scrypt, porque el navegador no tiene scrypt.

lucipher --features

## Qué es hoy

Cifrado autenticado
AES-256-GCM: confidencialidad e integridad. Un texto manipulado se rechaza al descifrar.
Isomorfo
El mismo código en Node ≥19 y navegadores modernos, vía crypto.subtle.
Interoperable
Cifra en un entorno, descifra en el otro. Verificado con Playwright.
Sin secretos ni deps
Cero dependencias, cero valores hardcodeados. Salt e IV aleatorios por mensaje.

cat example.mjs

## Uso

import LUCipher from 'lucipher';

const luc = new LUCipher('una-contraseña-fuerte');
const code = await luc.cipher('texto a cifrar');

try {
  const claro = await luc.desCipher(code);
  // 'texto a cifrar' — descifra también lo cifrado en Node
} catch {
  // manipulado, corrupto o contraseña incorrecta
}

! Con honestidad

LUCipher es, ante todo, un ejercicio de aprendizaje sobre criptografía y un pet-project para disfrutar construyendo algo que además me resulta útil en mis proyectos.

Usa primitivas estándar de Node y del navegador —nada de cripto casera— y sigue buenas prácticas: cifrado autenticado, KDF con sal, aleatoriedad por mensaje. Pero no ha pasado una auditoría profesional. Para secretos críticos, apóyate en librerías consolidadas y revisadas por expertos.

Dicho esto: pasó de ser un juguete inseguro a algo con fundamentos sólidos, y ese viaje —de la idea ingenua al diseño correcto— es justo lo que hace que valga la pena.