Licenza in abbonamento con codice Pro cifrato
Una licenza in abbonamento a tempo con un periodo di tolleranza, in cui il codice riservato all’abbonamento è protetto con la cifratura del codice di Babel Obfuscator.
Gli abbonamenti richiedono due comportamenti che una semplice data di scadenza non offre: un periodo di tolleranza, perché i clienti paganti non restino bloccati nell’istante in cui un rinnovo è in ritardo, e un controllo che non si possa aggirare modificando un file di configurazione. Questo esempio fa entrambe le cose e lega le funzionalità premium (“pro”) all’abbonamento con la cifratura del codice: il metodo Pro viene eseguito solo finché l’abbonamento, compreso il periodo di tolleranza, è valido, perché la Babel Virtual Machine ottiene la password di decifratura dalla licenza.
Esempio di codice
git clone https://github.com/babelfornet/subscription-license-console-example.gitProSuite è un’applicazione console con una funzionalità di base gratuita e una funzionalità Pro cifrata;
LicenseGenerator emette licenze in abbonamento con durata e tolleranza configurabili.
Due date: rinnovo e limite definitivo
La licenza contiene due date:
- la
ExpireDateapplicata dal motore, impostata sulla fine del periodo di tolleranza (il limite definitivo), e - un campo
subscription-end, non vincolante, che indica quando va fatto il rinnovo.
DateTime subscriptionEnd = now.AddDays(days); // soft end — renewal due
DateTime hardCutoff = subscriptionEnd.AddDays(grace); // engine-enforced end of grace
var license = new StringLicense { ExpireDate = hardCutoff };
license
.ForAssembly(assemblyFullName)
.WithUniqueId("SUBSCR-")
.WithHardwareKey(HardwareId.Create().ToMachineKey())
.WithField(Secrets.SubscriptionEndField, subscriptionEnd.ToString("O"))
.WithField(Secrets.ProSource, Secrets.ProPassword.Encrypt(Secrets.FieldSecret))
.LicensedTo("Demo Customer", "demo@example.com", "ACME Corp");Babel Licensing rifiuta automaticamente la licenza una volta superata ExpireDate, quindi il limite
definitivo non richiede codice apposito. L’applicazione deve solo distinguere lo stato attivo da quello
in tolleranza, e lo fa confrontando il campo non vincolante subscription-end con l’ora corrente:
var now = DateTime.UtcNow;
if (subEnd.HasValue && now > subEnd.Value)
{
int graceDaysLeft = (int)Math.Ceiling(((license.ExpireDate ?? now) - now).TotalDays);
return new SubscriptionStatus(SubscriptionState.Grace, subEnd, graceDaysLeft,
$"Subscription lapsed — grace period active ({graceDaysLeft} day(s) left). Please renew.");
}La funzionalità Pro cifrata
Il metodo Pro è cifrato; la sua password arriva dalla licenza attraverso l’hook get password.
È questo a legare il codice cifrato all’abbonamento: finché la licenza supera la convalida
(attiva o in tolleranza) l’hook restituisce la password e il metodo viene eseguito; superato il limite
definitivo, Validate() genera un’eccezione e l’hook non può più fornire la password.
[Obfuscation(Feature = "msil encryption:internal=true;source=pro;password=Pr0-Su1te-2026-K3y", Exclude = false)]
public static string Forecast(double[] series) { /* premium analytics */ }
[Obfuscation(Feature = "msil encryption get password")]
internal static string GetSourcePassword(string source)
{
var license = Validate(); // throws once past the end of grace
var field = license.Fields.FirstOrDefault(f => f.Name == source)
?? throw new InvalidOperationException($"License does not grant source '{source}'.");
return field.Value.Decrypt(Secrets.FieldSecret);
}Eseguire l’esempio
# Build in Release — Babel encrypts Pro.Forecast.
dotnet build src/ProSuite/ProSuite.csproj -c Release
# Mint a subscription license: active for 30 days, 7-day grace.
dotnet run --project src/LicenseGenerator -- --days 30 --grace 7
cp ProSuite.lic src/ProSuite/bin/Release/net8.0/
dotnet src/ProSuite/bin/Release/net8.0/ProSuite.dllEmetti di nuovo la licenza per passare da uno stato all’altro:
dotnet run --project src/LicenseGenerator -- --days -2 --grace 7 # lapsed, in grace
dotnet run --project src/LicenseGenerator -- --expired # past grace| Stato | Condizione | Funzionalità Pro |
|---|---|---|
| Attivo | prima della fine dell’abbonamento | viene eseguita |
| Tolleranza | dopo la fine dell’abbonamento, prima del limite definitivo | viene eseguita, con un avviso di rinnovo |
| Scaduto | dopo il limite definitivo | bloccata: la BVM non può decifrarla |
Superato il periodo di tolleranza, l’applicazione lo dimostra provando comunque a chiamare il metodo Pro:
Subscription expired: License expired
Basic average: 13.63
Pro forecast is locked. Renew your subscription to restore access.
(proof) encrypted Pro.Forecast blocked: License expiredCon la fatturazione ricorrente, la stessa licenza è normalmente emessa e rinnovata dal Babel Licensing Service, che può accorciare il periodo di validità e inviare i rinnovi automaticamente. La licenza a file offline mostrata qui è il modo più semplice per mostrare i passaggi tra gli stati attivo, in tolleranza e scaduto.
keys.pem e le password dell’esempio hanno solo scopo dimostrativo. Conserva offline la chiave privata
RSA ed emetti le licenze dal lato del produttore; con l’applicazione viene distribuita solo la chiave pubblica.