Skip to Content
Nouvelle version 12 disponible 🎉
LicensingLicence d’essai par numéro de série

Licence d’essai par numéro de série

Les licences d’essai permettent aux éditeurs de logiciels de proposer à des clients potentiels des versions d’essai à durée limitée de leurs applications.

Cet article présente le principe des licences d’essai par numéro de série et en montre l’implémentation dans une application console d’exemple. Le code fourni montre comment créer une licence d’essai qui expire après un certain nombre de jours et limite le nombre d’exécutions autorisées. Il montre aussi comment utiliser des techniques de chiffrement pour protéger du code sensible qui ne s’exécute que si la licence est valide. En comprenant la formule de la licence d’essai par numéro de série et en examinant le code qui l’accompagne, les développeurs voient comment utiliser Babel Licensing pour proposer des versions d’essai de leurs logiciels.

Exemple de code

Pour accéder au code du projet TrialLicense et l’étudier plus en détail, vous pouvez cloner le dépôt depuis GitHub avec la commande suivante :

git clone https://github.com/babelfornet/trial-license-string-console-example.git

Le projet TrialLicense montre comment implémenter un système de licences d’essai avec Babel Licensing dans une application console. Ce projet d’exemple est compatible avec Windows, Linux et macOS. En clonant le dépôt, vous disposez du code source complet, ce qui vous permet d’entrer dans les détails de l’implémentation, d’examiner les différents composants et de découvrir les fonctionnalités du système de licences d’essai.

Le projet utilise le package NuGet Babel Obfuscator pour obfusquer et chiffrer le code pendant le build.

Pour activer Babel Obfuscator, réglez la variable d’environnement BABEL_LICENSE sur le chemin du fichier de licence, ou sur la clé de licence flottante.

Le code chiffré ne peut s’exécuter qu’avec un numéro de série valide contenant le mot de passe de déchiffrement.

Exemple de licence d’essai

Pour démarrer l’application, ouvrez une fenêtre de shell, accédez au dossier Debug du projet, puis exécutez la commande TrialLicense en appuyant sur ENTER. L’application s’exécute alors.

Génération de la licence d’essai

Le code suivant génère le numéro de série d’une licence d’essai :

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");

Voici le détail de son fonctionnement :

  1. HardwareId.Create().ToMachineKey() génère une clé propre au matériel, qui identifie de manière unique la machine en cours. Cette clé sert à lier la licence d’essai à la machine en cours.
  2. (RSASignature)Pem.ReadSignature("Keys.pem") lit la clé privée RSA dans le fichier « Keys.pem ». Cette clé sert à signer la licence et à en valider l’authenticité.
  3. new StringLicense() crée une nouvelle instance de la classe StringLicense, qui représente la licence d’essai.
  4. .ForAssembly(Assembly.GetExecutingAssembly()) indique que la licence est associée à l’assembly en cours.
  5. .WithUniqueId() génère un identifiant unique pour la licence.
  6. .WithHardwareKey(hardwareKey) lie la licence à la machine en cours en l’associant à la clé matérielle générée au point 1.
  7. .WithTrialDays(2) fixe la période d’essai à 2 jours, au terme desquels la licence expire.
  8. .WithMaximumRunCount(3) définit le nombre maximal d’exécutions autorisées pour la version d’essai.
  9. .WithField("source1", "p@ssw0rd1".Encrypt("!sEcr3tp@sswOrD!")) ajoute à la licence un champ nommé « source1 » et lui donne pour valeur un mot de passe chiffré. Ce mot de passe sert à déchiffrer le code concerné pour l’exécuter lorsque la licence est valide.
  10. .SignWith(sign) signe la licence avec la clé privée RSA obtenue à l’étape 2, ce qui garantit son intégrité et son authenticité.
  11. lic.ToReadableString("ASCII") convertit l’objet licence en une chaîne ASCII.
  12. Le numéro de série de licence obtenu est stocké dans le registre, avec la clé publique utilisée pour la validation.

Ce code montre comment générer le numéro de série d’une licence d’essai, y compris sa protection par chiffrement et son stockage dans le registre. La licence d’essai peut être validée avec la clé publique correspondante pour s’assurer de son authenticité et appliquer les restrictions d’essai, comme la durée de l’essai et le nombre d’exécutions.

Validation de la licence d’essai

L’extrait de code suivant montre une implémentation concrète de ce processus. Il utilise Babel Licensing pour valider le numéro de série d’essai.

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); }

Ici, la clé publique utilisée pour valider la signature de la licence est récupérée dans les informations du fichier de licence. La valeur associée à la clé « Key » est lue, puis déchiffrée avec le mot de passe de déchiffrement « pk_p@sswOrd ».

Une instance de la classe StringLicenseManager est créée pour gérer la validation de licence. La propriété SignatureProvider du gestionnaire reçoit un objet RSASignature créé à partir de la clé publique récupérée. Le gestionnaire utilise ainsi la clé publique pour valider la signature de la licence.

Babel.Licensing.ILicense license = manager.Validate(serial);

La méthode manager.Validate(serial) est appelée pour valider la licence. Le numéro de série de licence stocké dans la variable serial est passé en argument. Si le numéro de série est valide et respecte toutes les restrictions de licence, un objet licence qui implémente l’interface Babel.Licensing.ILicense est renvoyé. Il représente la licence validée.

Enfin, la durée d’essai restante et le nombre d’exécutions restantes sont affichés dans la console.

En résumé, ce code valide un numéro de série de licence en récupérant le numéro de série et la clé publique dans le registre, en configurant le gestionnaire de licences avec la clé publique et en appelant la méthode de validation. Il affiche ensuite le résultat de la validation et, le cas échéant, les informations de licence pertinentes, comme la durée d’essai et le nombre d’exécutions.

Exécution du code chiffré

Le code fourni montre l’exécution de code chiffré et la façon dont il est récupéré avec Babel Obfuscator. Son fonctionnement est le suivant :

Tout d’abord, deux méthodes interviennent :

[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!"); }

La méthode GetEncryptedCodePassword sert de point d’entrée pour récupérer le mot de passe du code chiffré. Elle appelle la méthode EncryptedGetEncryptedCodePassword en lui passant une valeur de source en paramètre. Cette méthode a pour rôle d’extraire de la licence le mot de passe du code chiffré associé à la source indiquée. Voir le chiffrement du code de Babel Obfuscator pour en savoir plus sur le code chiffré avec un mot de passe.

Dans EncryptedGetEncryptedCodePassword, les étapes sont les suivantes :

  1. Le code récupère le numéro de série de licence et la clé publique correspondante dans le fichier de licence.
  2. La clé publique est déchiffrée avec le mot de passe « pk_p@sswOrd ».
  3. Une instance de StringLicenseManager est créée pour valider la licence avec la clé publique déchiffrée.
  4. La licence est validée en passant le numéro de série à la méthode Validate du gestionnaire.
  5. Si le numéro de série est valide et respecte toutes les restrictions de licence, un objet licence est renvoyé.
  6. Le mot de passe du code chiffré associé à la source indiquée est récupéré dans les champs de la licence.
  7. Enfin, le mot de passe chiffré est déchiffré avec le secret « !sEcr3tp@sswOrD! », puis renvoyé.

Babel Obfuscator sert en outre à obfusquer et à chiffrer le code. Les fonctionnalités d’obfuscation utilisées sont les suivantes :

  1. Pour la méthode ExecuteEncryptedCode :
[Obfuscation(Feature = "msil encryption:source=source1;password=p@ssw0rd1;internal=true", Exclude = false)] private void ExecuteEncryptedCode() { Console.WriteLine("Encrypted code running"); }

La fonctionnalité msil encryption est appliquée avec la source indiquée (« source1 »), le mot de passe de chiffrement (« p@ssw0rd1 ») et internal défini sur true. Cette obfuscation garantit que le code de cette méthode est chiffré et protégé.

En combinant ces éléments, le mot de passe du code chiffré est récupéré dans la licence avec Babel Obfuscator. Le mot de passe validé permet de déchiffrer et d’exécuter le code chiffré de la méthode ExecuteEncryptedCode, ce qui offre un environnement d’exécution sûr et contrôlé pour les sections de code sensibles.

Last updated on