Skip to Content
Nouvelle version 12 disponible 🎉
ObfuscatorChiffrement du codeChiffrement du code lié à la licence

Chiffrement du code lié à la licence

Le chiffrement du code lié à la licence est une variante du code protégé par mot de passe dans laquelle le mot de passe qui déverrouille une méthode chiffrée n’est pas une constante fixe inscrite dans le build, mais une valeur lue à l’exécution dans la licence du client.

La méthode protégée est toujours livrée dans l’assembly obfusqué, mais son code reste chiffré tant qu’une licence valide ne fournit pas le bon mot de passe. Une fonctionnalité sensible ou premium ne s’exécute donc que pour les utilisateurs dont la licence l’autorise, tandis que le reste de l’application continue de fonctionner normalement pour tous les autres.

C’est le mécanisme que Babel Obfuscator utilise en interne pour conditionner ses propres fonctionnalités sous licence. Il s’ajoute au chiffrement du code habituel que vous connaissez déjà : il n’y a rien de nouveau à installer, seulement une règle et un petit hook à écrire.

Fonctionnement

  1. Marquer le code à protéger. Une règle XML (ou l’attribut Obfuscation) sélectionne les méthodes ou les types à chiffrer et leur attribue un nom de source et un mot de passe, en conservant le code chiffré dans l’assembly (Internal = true).
  2. Fournir un hook de mot de passe. Une méthode marquée [Obfuscation(Feature = "msil encryption get password")] reçoit le nom de la source et renvoie le mot de passe de cette source en lisant un champ de la licence chargée.
  3. Exécuter. Au premier appel de la méthode protégée, la machine virtuelle Babel (BVM) appelle le hook pour obtenir le mot de passe de la source. Si la licence contient le champ attendu, la méthode est déchiffrée et exécutée ; si le champ est absent ou si la valeur est incorrecte, le déchiffrement échoue et la méthode ne peut pas s’exécuter : la fonctionnalité est donc verrouillée de fait.

Seules les méthodes qui correspondent à une règle dotée d’un <Source> sont liées à la licence. Les méthodes chiffrées avec la simple option --msilencryption (sans source) sont déverrouillées à partir de l’assembly lui-même et continuent de s’exécuter sans licence ; l’application sans licence continue donc de fonctionner, et seules les fonctionnalités conditionnées par la licence restent inaccessibles.

Chiffrer le code

Ajoutez une règle qui chiffre le code sensible et le lie à une source nommée et à un mot de passe :

<Rule name="encrypt premium" feature="msil encryption" exclude="false"> <Target>Methods</Target> <Pattern>ACME.Premium::*</Pattern> <Properties> <Source>premium</Source> <Password>Xa9!k2$LpQ7r</Password> <Internal>true</Internal> </Properties> <Description>Encrypt the premium feature, unlocked by the license.</Description> </Rule>

La même chose peut s’exprimer directement dans le code avec l’attribut Obfuscation :

[Obfuscation(Feature = "msil encryption:internal=true;source=premium;password=Xa9!k2$LpQ7r", Exclude = false)] internal class Premium { public string Run() => "premium result"; }

Le <Password> que vous définissez à la génération doit correspondre à la valeur que le hook de mot de passe renvoie pour cette source à l’exécution. Dans une conception liée à la licence, le hook lit cette valeur dans la licence : stockez donc la même valeur dans le champ de licence que vous émettez pour vos clients.

Lire le mot de passe dans la licence

Déclarez un seul hook qui fait correspondre un nom de source au mot de passe contenu dans la licence. L’exemple ci-dessous utilise Babel Licensing pour rechercher une fonctionnalité sous licence et renvoyer sa valeur :

[Obfuscation(Feature = "msil encryption get password")] internal static string GetSourcePassword(string source) { var license = LicenseManager.Instance.License; var feature = license.Features.FirstOrDefault(f => f.Name == source); if (feature == null) throw new ApplicationException($"feature '{source}' is not licensed"); return Encoding.UTF8.GetString(feature.Data); }

À l’exécution, la BVM appelle GetSourcePassword("premium") ; le hook renvoie le mot de passe stocké dans la licence du client, et la méthode premium est déchiffrée puis exécutée.

Le hook doit être accessible au code que Babel injecte : déclarez-le donc public ou internal. Si vous le laissez private ou protected, Babel élargit automatiquement sa visibilité à internal pendant l’obfuscation (il n’est jamais rendu public), afin que le code injecté puisse l’appeler.

Pour une implémentation complète et exécutable, comprenant la classe LicenseManager et l’émission de licences par édition, voir l’exemple Licences basées sur des fonctionnalités.

Compatible avec tous les modes de remise de la licence

Comme le hook se contente de lire l’objet licence chargé, le chiffrement du code lié à la licence ne dépend pas de la façon dont cette licence parvient à l’application. Il fonctionne sans modification avec tous les modes de remise de Babel Licensing :

Quel que soit le mode choisi, une fois que votre code de gestion des licences a validé et chargé la licence, le hook de mot de passe peut lire le champ dont il a besoin et la fonctionnalité protégée se déverrouille.

Vous préférez garder le code chiffré entièrement hors de l’assembly principal ? Associez ce mécanisme aux fichiers de code externes pour déployer la méthode chiffrée avec la licence.

Last updated on