Licenza seriale di prova
In questo articolo esaminiamo il concetto di licenza seriale di prova e ne mostriamo l’implementazione con un’applicazione console di esempio. Il codice fornito mostra come creare una licenza di prova che scade dopo un certo numero di giorni e limita il numero di esecuzioni consentite. Mostra inoltre l’uso di tecniche di cifratura per proteggere il codice sensibile, che viene eseguito solo se la licenza è valida. Comprendendo lo schema della licenza seriale di prova ed esaminando il codice che lo accompagna, gli sviluppatori possono capire come usare Babel Licensing per realizzare versioni di prova dei loro prodotti software.
Esempio di codice
Per accedere al codice del progetto TrialLicense ed esaminarlo piĂą a fondo, puoi clonare il repository da GitHub con il seguente comando:
git clone https://github.com/babelfornet/trial-license-string-console-example.gitIl progetto TrialLicense mostra come realizzare un sistema di licenze di prova con Babel Licensing in un’applicazione console. Questo progetto di esempio è compatibile con Windows, Linux e macOS. Clonando il repository hai accesso al codice sorgente completo, e puoi così approfondire i dettagli dell’implementazione, esaminare i diversi componenti ed esplorare le funzionalità del sistema di licenze di prova.
Il progetto usa il pacchetto NuGet di Babel Obfuscator per offuscare e cifrare il codice durante il processo di build.
Per attivare Babel Obfuscator, imposta la variabile d’ambiente BABEL_LICENSE sul percorso del file di licenza, oppure sulla chiave della licenza flottante.
Il codice cifrato può essere eseguito solo con un numero di serie valido che contiene la password di decifratura.

Esempio di licenza di prova
Per avviare l’applicazione, apri una finestra della shell, spostati nella cartella Debug del progetto ed esegui il comando TrialLicense premendo ENTER. L’applicazione viene così eseguita.
Generazione della licenza di prova
Il codice seguente genera il numero di serie di una licenza di prova:
string hardwareKey = HardwareId.Create().ToMachineKey();
var sign = (RSASignature)Pem.ReadSignature("Keys.pem");
var lic = new StringLicense() // Create a new string license
.ForAssembly(Assembly.GetExecutingAssembly()) // The license is for this assembly
.WithUniqueId() // Unique ID for the license
.WithHardwareKey(hardwareKey) // Lock to the current machine
.WithTrialDays(2) // Give 2 days trial
.WithMaximumRunCount(3) // Allow 3 runs
.WithField("source1", "p@ssw0rd1".Encrypt("!sEcr3tp@sswOrD!")) // Set the encrypted code password
.SignWith(sign); // Sign the license with the private key
// Convert the license object to an ASCII string
string serial = lic.ToReadableString("ASCII");Ecco in dettaglio che cosa fa:
HardwareId.Create().ToMachineKey()genera una chiave specifica dell’hardware che identifica in modo univoco il computer corrente. Questa chiave serve a vincolare la licenza di prova al computer corrente.(RSASignature)Pem.ReadSignature("Keys.pem")legge la chiave privata RSA dal file “Keys.pem”. Questa chiave serve a firmare la licenza e a convalidarne l’autenticità .new StringLicense()crea una nuova istanza della classeStringLicense, che rappresenta la licenza di prova..ForAssembly(Assembly.GetExecutingAssembly())specifica che la licenza è associata all’assembly corrente..WithUniqueId()genera un identificatore univoco per la licenza..WithHardwareKey(hardwareKey)vincola la licenza al computer corrente associandola alla chiave hardware generata al punto 1..WithTrialDays(2)imposta il periodo di prova a 2 giorni: la licenza scade al termine di questo periodo..WithMaximumRunCount(3)imposta il numero massimo di esecuzioni consentite per la versione di prova..WithField("source1", "p@ssw0rd1".Encrypt("!sEcr3tp@sswOrD!"))aggiunge alla licenza un campo di nome “source1” e ne imposta il valore su una password cifrata. Questa password servirà a decifrare codice specifico da eseguire quando la licenza è valida..SignWith(sign)firma la licenza con la chiave privata RSA ottenuta al punto 2, garantendone l’integrità e l’autenticità .lic.ToReadableString("ASCII")converte l’oggetto licenza in una rappresentazione in stringa ASCII.- Il numero di serie della licenza così ottenuto viene salvato nel registro, insieme alla chiave pubblica usata per la convalida.
Questo codice mostra il processo di generazione del numero di serie di una licenza di prova, compresa la protezione con la cifratura e il salvataggio nel registro. La licenza di prova può essere convalidata con la chiave pubblica corrispondente per garantirne l’autenticità e applicare le restrizioni di prova, come la durata della prova e il limite di esecuzioni.
Convalida della licenza di prova
Il frammento di codice seguente mostra un’implementazione pratica di questo processo. Usa Babel Licensing per convalidare il numero di serie di prova.
var store = new LicenseStore();
store.Load();
if (store.Serial == null)
{
Console.WriteLine("No serial found");
return;
}
// Get the public key from the key to validate the license signature
string publicKey = Convert.ToString(store.Key).Decrypt("pk_p@sswOrd");
var manager = new StringLicenseManager();
// The public key is used to validate the license signature
manager.SignatureProvider = RSASignature.FromKeys(publicKey);
// Validate the serial
// A license object is returned if the serial is valid and all license restrictions are met
Babel.Licensing.ILicense license = manager.Validate(store.Serial);
Console.WriteLine("Serial {0} is valid", license.Id);
var trial = license.Restrictions.OfType<TrialRestriction>().FirstOrDefault();
if (trial != null)
{
Console.WriteLine("Trial time left: {0}", trial.TimeLeft);
Console.WriteLine("Runs left: {0}", trial.RunCountLeft);
}Qui la chiave pubblica usata per convalidare la firma della licenza viene recuperata dalle informazioni del file di licenza. Viene letto il valore associato alla chiave “Key”, e la password di decifratura “pk_p@sswOrd” viene usata per decifrare il valore salvato.
Viene creata un’istanza della classe StringLicenseManager per gestire il processo di convalida della licenza. La proprietà SignatureProvider del gestore viene impostata su un oggetto RSASignature creato dalla chiave pubblica recuperata. In questo modo il gestore usa la chiave pubblica per convalidare la firma della licenza.
Babel.Licensing.ILicense license = manager.Validate(serial);Per convalidare la licenza viene chiamato il metodo manager.Validate(serial). Il numero di serie della licenza contenuto nella variabile serial viene passato come argomento. Se il numero di serie è valido e soddisfa tutte le restrizioni della licenza, viene restituito un oggetto licenza che implementa l’interfaccia Babel.Licensing.ILicense. Rappresenta la licenza convalidata.
Infine il tempo di prova rimanente e il numero di esecuzioni rimaste vengono stampati sulla console.
Nel complesso, questo codice convalida il numero di serie di una licenza: recupera dal registro il numero di serie e la chiave pubblica, configura il gestore di licenze con la chiave pubblica e chiama il metodo di convalida. Mostra poi il risultato della convalida e le informazioni pertinenti della licenza, come il tempo di prova e il numero di esecuzioni, quando sono disponibili.
Esecuzione del codice cifrato
Il codice seguente mostra l’esecuzione del codice cifrato e come recuperarlo con Babel Obfuscator. Vediamo come funziona:
Innanzitutto, sono coinvolti due metodi:
[Obfuscation(Feature = "msil encryption get password", Exclude = false)]
internal static string GetEncryptedCodePassword(string source)
{
return EncryptedGetEncryptedCodePassword(source);
}
[Obfuscation(Feature = "msil encryption", Exclude = false)]
private static string EncryptedGetEncryptedCodePassword(string source)
{
var store = new LicenseStore();
store.Load();
if (store.Serial == null)
{
throw new Exception("No serial found");
}
// Get the public key from the key to validate the license signature
string publicKey = Convert.ToString(store.Key).Decrypt("pk_p@sswOrd");
var manager = new StringLicenseManager();
// The public key is used to validate the license signature
manager.SignatureProvider = RSASignature.FromKeys(publicKey);
// Validate the serial
// A license object is returned if the serial is valid and all license restrictions are met
Babel.Licensing.ILicense license = manager.Validate(store.Serial);
// Reuse the same secret used to decrypt the code password
return license.Fields.First(item => item.Name == source).Value.Decrypt("!sEcr3tp@sswOrD!");
}Il metodo GetEncryptedCodePassword fa da punto di ingresso per recuperare la password del codice cifrato. Chiama il metodo EncryptedGetEncryptedCodePassword passando come parametro un valore di origine. Lo scopo di questo metodo è estrarre dalla licenza la password del codice cifrato associata all’origine indicata. Vedi la cifratura del codice di Babel Obfuscator per saperne di più sul codice cifrato con una password.
All’interno di EncryptedGetEncryptedCodePassword avvengono i seguenti passi:
- Il codice recupera dal file di licenza il numero di serie della licenza e la chiave pubblica corrispondente.
- La chiave pubblica viene decifrata con la password “pk_p@sswOrd”.
- Viene creata un’istanza di
StringLicenseManagerper convalidare la licenza con la chiave pubblica decifrata. - La licenza viene convalidata passando il numero di serie al metodo
Validatedel gestore. - Se il numero di serie è valido e soddisfa tutte le restrizioni della licenza, viene restituito un oggetto licenza.
- La password del codice cifrato associata all’origine specificata viene recuperata dai campi della licenza.
- Infine la password cifrata viene decifrata con il segreto “!sEcr3tp@sswOrD!” e restituita.
Inoltre Babel Obfuscator viene usato per offuscare e cifrare il codice. Le funzionalitĂ di offuscamento usate sono:
- Per il metodo
ExecuteEncryptedCode:
[Obfuscation(Feature = "msil encryption:source=source1;password=p@ssw0rd1;internal=true", Exclude = false)]
private void ExecuteEncryptedCode()
{
Console.WriteLine("Encrypted code running");
}La funzionalità msil encryption viene applicata con l’origine specificata (“source1”), la password di cifratura (“p@ssw0rd1”) e internal impostato su true. Questo offuscamento garantisce che il codice all’interno del metodo sia cifrato e protetto.
Combinando questi componenti, la password del codice cifrato può essere recuperata dalla licenza con Babel Obfuscator. La password convalidata permette di decifrare ed eseguire il codice cifrato del metodo ExecuteEncryptedCode, offrendo un ambiente di esecuzione sicuro e controllato per le sezioni di codice sensibili.