Skip to content
← Todas las publicaciones
· Delta1 Labs Licenciamiento.NETGuía

Rotar las claves de firma de licencias sin dejar fuera a los clientes

Tus claves de licencia y tus leases valen tanto como la clave que las firma. Así se rota esa clave de firma a una nueva sin interrupciones: confianza solapada con AdditionalPublicKeysBase64, un despliegue por fases, y cómo los leases y los archivos sin conexión hacen segura la transición.

Una clave de licencia es un claim —«este cliente posee la edición Pro, 3 puestos, hasta marzo que viene»— y tu app cree ese claim por una sola razón: lo firmó una clave en la que tu app confía. Esa clave de firma es la raíz de todo el sistema. Todo lo que viene después —las ediciones, los topes de puestos, la caducidad, los leases que permiten a una máquina activada funcionar sin conexión— hereda su confianza de esa única clave. Lo cual es también por lo que rotarla asusta: cambia la raíz y arriesgas invalidar cada licencia que has emitido jamás.

No tienes por qué. Este artículo recorre cómo rotar una clave de firma de Keyright sin ninguna interrupción visible para el cliente: qué protege realmente la clave, por qué un cambio ingenuo deja a todos fuera, cómo la confianza solapada hace la transición fluida, y cómo los leases y los archivos sin conexión deciden cuánto tiene que durar el solape.

Qué protege realmente la clave de firma

Keyright es offline-first. Cuando emites una licencia, el servicio firma un payload canónico de claims con la clave de firma privada de tu producto y te devuelve una cadena de clave pegable. Tu app embebe solo la clave pública correspondiente. En el momento de la validación la app verifica la firma localmente —sin red— y solo entonces confía en el nivel, la caducidad y el número de puestos que contiene. La activación añade un segundo artefacto firmado: un lease de corta vida (14 días por defecto) ligado a la máquina, también firmado por esa clave, que es lo que permite a una máquina activada seguir funcionando sin conexión hasta que la ventana de gracia del lease se agota.

Servicio emisorsign(claims, PRIV)sign(lease, PRIV)clave de licenciaclaims firmadosleasefirmado, por máquinaApp (embebe clave PÚBLICA)verify(sig, PUB) localmente — sin redluego confía en nivel · caducidad · puestos

Así que la clave hace mucho trabajo de carga, y va embebida en software que ya has distribuido. Esa es exactamente la propiedad que quieres por seguridad —la raíz de confianza está en el cliente, no en un servidor al que un atacante pudiera engañar con ingeniería social— y exactamente la propiedad que convierte la rotación en un problema de diseño en lugar de en pulsar un botón.

Por qué el cambio ingenuo es un desastre

Imagina que sospechas que la clave privada se filtró. El movimiento obvio: generar un nuevo par de claves, re-firmar las licencias nuevas con ella, distribuir una compilación de la app que embeba la clave pública nueva. ¿Listo?

No. En el instante en que esa compilación llega a un cliente, cada licencia y cada lease firmados por la clave antigua fallan la verificación en su máquina. La firma ya no coincide con la clave embebida, así que un cliente que pagó y activó la semana pasada cae a la edición gratuita en su próximo arranque. Has convertido una rotación preventiva en una caída general en el campo.

El fallo es estructural: la app confía en exactamente una clave, y se la cambiaste por debajo a artefactos que siguen siendo válidos. El arreglo es confiar en dos claves durante un tiempo.

Confianza solapada: la única idea que lo hace seguro

Cada SDK de Keyright verifica una licencia o lease entrante contra una clave pública primaria y contra una lista de claves públicas adicionales. Si cualquier clave de confianza verifica la firma, el artefacto se acepta. Eso convierte un corte brusco en una ventana de solape.

Aquí está el SDK de .NET en operación normal: una clave:

var keyright = new KeyrightClient(new KeyrightOptions
{
    Product = "my-app",
    ServiceUrl = "https://license.example.com",
    PublicKeyBase64 = "<current public key>",
});

Y aquí está a mitad de rotación. La clave nueva es primaria; la clave saliente viaja en AdditionalPublicKeysBase64:

var keyright = new KeyrightClient(new KeyrightOptions
{
    Product = "my-app",
    ServiceUrl = "https://license.example.com",
    PublicKeyBase64 = "<NEW public key>",
    // Keep the old key valid through the rotation window:
    AdditionalPublicKeysBase64 = new[] { "<previous public key>" },
});

Una licencia firmada por la clave antigua sigue verificando (coincide con una clave adicional). Una licencia o lease firmados por la clave nueva también verifican (coinciden con la primaria). Nadie pierde el nivel. Las dos claves coexisten exactamente mientras los artefactos firmados por la antigua sigan en circulación, y entonces la retiras.

La rotación, paso a paso

1. Rota la clave en el servicio. Cada producto posee su propia clave de firma. Una llamada autenticada la rota; la clave antigua se conserva como clave previa para que aún puedas ver qué firmó, y la respuesta te entrega la clave pública nueva para embeber:

curl -X POST "$BASE/admin/products/my-app/signing-key" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"rotate": true}'
# → { "signingPublicKey": "<NEW public key>", ... }

(Lo mismo vive en el panel bajo la pestaña Signing key del producto: la rotación, la importación y la lista de claves previas están en su sección Advanced.) Tras esto, las licencias recién emitidas y los leases recién firmados usan la clave nueva. Las licencias ya emitidas no cambian: sus firmas se hicieron en el momento de emisión y no cambian retroactivamente.

2. Distribuye una compilación que confíe en ambas claves. Añade la clave nueva como PublicKeyBase64 y la clave saliente a AdditionalPublicKeysBase64, como arriba. Publícala por tu canal habitual. De aquí en adelante, los clientes aceptan artefactos firmados por cualquiera de las claves.

3. Deja que los leases lleven la clave nueva al campo. No tienes que perseguir a nadie. Como una máquina activada refresca su lease al acercarse a la caducidad, cada cliente en línea vuelve a tomar lease de forma natural bajo la clave nueva dentro de una ventana de gracia: 14 días por defecto. Tras un par de ventanas, esencialmente cada lease activo en el campo está firmado con la clave nueva.

rotarel servicio firmacon la clave nuevacompilación doblenueva = primariaantigua = adicionalventana de gracialos leases serefrescan con la nuevaretirar la antiguasiguiente buildclave antigua de confianzaclave nueva de confianza

4. Retira la clave antigua. Una vez que ningún artefacto firmado por la clave antigua pueda seguir vivo —cada lease firmado por ella ha caducado, y ningún archivo sin conexión independiente firmado por ella sigue en servicio— distribuye una compilación que la retire de AdditionalPublicKeysBase64. Ahora solo la clave nueva es de confianza. La rotación está completa, y si la clave privada antigua se había filtrado, cualquier cosa que firmara ahora no vale nada para un atacante.

Qué fija la duración del solape

El solape no puede ser más corto que el artefacto de mayor vida que firmó la clave antigua. Tres casos:

  • Las máquinas activadas en línea avanzan al ritmo de tu TTL de lease (14 días por defecto). Una ventana de gracia después de que el servicio cambie de clave, esencialmente todos han vuelto a tomar lease.
  • Las máquinas mucho tiempo sin conexión a las que se les emitió un lease sin conexión de TTL largo (365 días por defecto) permanecen en la clave antigua hasta que ese lease caduca. Si tienes esas, tu solape es un año, no dos semanas: planifícalo.
  • Los archivos de licencia sin conexión independientes no se refrescan en absoluto; avanzan al ritmo de tus versiones. Un cliente en una instalación aislada mantiene la clave antigua de confianza hasta que adopta una compilación firmada por la nueva. Mantén la clave antigua en la lista hasta que hayas confirmado que esos clientes han migrado.

La regla general: mantén la clave pública antigua en AdditionalPublicKeysBase64 hasta que el último artefacto que firmó haya caducado o sido reemplazado, y luego retírala en la siguiente versión. No hay penalización por dejarla un poco más, y sí una real por retirarla demasiado pronto.

Si la clave privada se filtró de verdad

La rotación re-apunta la confianza futura, pero una clave privada filtrada significa que un atacante puede falsificar licencias en las que tu app actualmente distribuida aún confía, hasta que adopten una compilación que ya no confíe en la clave antigua. Así que combina la rotación con la revocación. Keyright puede publicar una lista de revocación firmada, y la activación en línea te permite matar claves filtradas concretas para que una máquina activada-pero-revocada caiga a la edición gratuita en su próximo refresco de lease. Para un compromiso confirmado, la secuencia honesta es: rota, distribuye rápido la compilación de doble clave, revoca las claves emitidas malas conocidas, y acorta el solape tan agresivamente como tus clientes sin conexión permitan.

Y recuerda el límite que se aplica a todo el licenciamiento del lado del cliente: la verificación corre en la máquina del usuario, así que un atacante decidido con un decompilador puede intentar parchear el chequeo por completo. Por eso justamente Keyright es compatible a nivel de formato con Nebula.NET: ofuscas y endureces el ensamblado que embebe la clave pública y realiza el chequeo, de modo que parchearlo cueste esfuerzo real. La clave de firma es la raíz criptográfica; la ofuscación protege el código que la hace cumplir.

Conectándolo

La rotación de clave de firma en Keyright es una operación de una sola llamada en el servidor más un cambio de una línea en el cliente, hecha segura por la confianza solapada y marcada por el tiempo de vida de tus leases. Genera o rota una clave desde la pestaña Signing key del producto (o el endpoint signing-key), embebe la nueva como PublicKeyBase64, mantén la saliente en AdditionalPublicKeysBase64 durante una ventana de lease —más tiempo si distribuyes archivos sin conexión— y luego retírala. Consulta la guía de integración del SDK de .NET para las opciones exactas y la página de seguridad y leases para ver cómo los leases deciden tu solape, o la página de producto de Keyright para el panorama completo. El plan gratuito basta para ensayar una rotación completa de principio a fin antes de depender de ella.

Prueba Nebula.NET

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