Skip to content
← Todas las publicaciones
· Delta1 Labs LicenciamientoSeguridadGuía

Revocación de licencias: hacer que una clave deje de funcionar, con y sin conexión

Emitir una licencia es fácil; hacer que una deje de funcionar tras un reembolso, una filtración o un contracargo es la mitad más difícil. Así funciona la revocación de verdad: el check-in en línea que falla hacia el estado bloqueado, las listas de revocación firmadas que llegan a los clientes sin conexión, y cómo acotar la ventana de exposición que nunca puedes cerrar del todo.

Todos los tutoriales de licenciamiento enseñan la emisión: generar una clave, firmarla, entregarla. Muchos menos enseñan la otra mitad, que es donde está la ingeniería de verdad: hacer que una clave deje de funcionar. Un cliente reembolsa. Una clave aparece en un foro. Llega un contracargo. Un empleado con la clave de la empresa se va. En cada caso necesitas que una clave que ya existe, en la máquina de otra persona, deje de conceder tu software. Eso es la revocación, y se comporta de forma muy distinta con y sin conexión.

Qué es la revocación, y qué no

Revocar una licencia es una declaración negativa firmada: el proveedor declara que la clave K ya no es válida. No alcanza ni borra nada del disco del cliente; cambia lo que tu app concluye la próxima vez que evalúa esa clave. Así que todo el problema se reduce a una pregunta: ¿cuándo vuelve la app a evaluar, y se entera de la revocación a tiempo?

Ese encuadre importa porque fija la expectativa honesta. La revocación nunca es instantánea en todas partes. Lo que controlas es la ventana entre revocar y que la clave quede muerta en una máquina dada. Tu trabajo es hacer esa ventana lo bastante pequeña para el riesgo, y nunca fingir que es cero.

Revocación en línea: fallar cerrado en el próximo check-in

El caso común es una app conectada. Marcas la clave como revocada en el servidor, y la próxima vez que el cliente habla con el servicio —una revalidación, una reactivación, un heartbeat— el servicio responde «revocada» y el cliente falla hacia el estado sin licencia.

var info = await client.ValidateOnlineAsync(key);
if (info.Status == LicenseStatus.Revoked)
{
    _cache.Clear();          // drop any cached lease so offline validate can't resurrect it
    EnterUnlicensedMode();   // fail closed — never throw and leave features on
}

La ventana de exposición aquí es tu intervalo de reverificación. Una lease vinculada a la máquina suele cachearse para que la app funcione sin conexión entre comprobaciones (no quieres llamar a casa en cada arranque); esa misma caché es lo que retrasa una revocación. Si la lease es válida 24 horas, una clave revocada sigue funcionando hasta 24 horas en esa máquina. Acorta la lease para encoger la ventana, a costa de requisitos de conectividad más frecuentes. Ese compromiso es la decisión de diseño: ata la vida de la lease a cuánta exposición cuesta realmente una clave filtrada o reembolsada.

Una advertencia: cuando detectes una revocación, limpia la lease cacheada. Si no, una app que se desconecta justo después de la revocación puede seguir validando contra la lease cacheada obsoleta hasta que caduque.

El problema sin conexión y la lista de revocación firmada

Un cliente totalmente sin conexión o aislado nunca hace check-in, así que lo de «revocada en el próximo check-in» nunca se dispara. La respuesta es llevar la revocación hasta el cliente como datos en los que pueda confiar sin red: una lista de revocación firmada (una CRL, en el sentido clásico). El proveedor publica el conjunto de ids de claves revocadas, firma esa lista con la misma clave privada que firma las licencias, y la distribuye: junto con una actualización de software, empujada por una herramienta de gestión, o llevada en un archivo para sistemas realmente aislados.

// The list is signed; verify it against the embedded public key before trusting a single entry.
RevocationList crl = RevocationList.Load(path);
if (!crl.VerifySignature(publicKey))
    throw new SecurityException("Revocation list signature invalid — ignoring it.");

if (crl.Contains(incomingLease.KeyId))
    EnterUnlicensedMode();   // known-bad key, even with no network

La firma es lo crucial: el cliente debe aceptar la lista sin conexión, así que la lista tiene que llevar su propia prueba de autenticidad, igual que la licencia. Un atacante que pudiera inyectar una lista falsa o truncada simplemente borraría su propia revocación. Como está firmada, una lista recortada o alterada falla la verificación y se ignora.

La latencia aquí es tu cadencia de distribución: la lista llega a una máquina cuando llega la próxima actualización. Es más lento que en línea, pero significa que una instalación aislada no queda permanentemente indefensa ante una clave reembolsada o filtrada.

El proveedor revocaclave marcada inválidaEn línea: próximo check-infalla cerrado en el intervaloSin conexión: CRL firmadallega con una actualizaciónLa app falla cerradamodo sin licencia

Tras la revocación: reemitir para el caso legítimo

No toda revocación es adversaria. Un cliente que hizo un contracargo por error, o cuya clave se filtró sin culpa suya, aún merece ejecutar tu software. Así que empareja la revocación con una reemisión limpia: revoca la clave comprometida, emite una nueva y deja que el cliente la active. Como la clave vieja está en la lista de revocación y la nueva no, las dos coexisten correctamente: la clave filtrada está muerta dondequiera que se propague, la nueva funciona. Evita la tentación de «desrevocar»; una clave revocada debería seguir revocada para siempre, y el cliente pasa a una credencial nueva.

Diseñar la ventana a propósito

La revocación obliga a una decisión explícita: ¿cuánto tiempo puede seguir funcionando una clave revocada en cada máquina? En línea, eso es el intervalo de lease/reverificación; sin conexión, es la cadencia de actualización más la CRL. Fija ambos según el riesgo, no por costumbre. Un puesto empresarial de alto valor que podría revenderse justifica leases cortas y CRL frecuentes; una herramienta barata de un solo usuario puede tolerar un día. El error es dejarlo implícito: enviar una lease cacheada de 30 días y luego sorprenderte de que una clave reembolsada siga funcionando cuatro semanas después.

La emisión mete una licencia en el mundo. La revocación es cómo mantienes autoridad sobre ella después, y un sistema de licenciamiento que hace una cosa pero no la otra solo parece terminado.

Prueba Nebula.NET

Endurece tu código .NET en minutos — empieza con la edición gratuita.