Skip to Content
Nouvelle version 12 disponible 🎉
ObfuscatorChiffrement du code

Chiffrement du code

La fonctionnalité de chiffrement du code de Babel Obfuscator permet de chiffrer l’intégralité du code pour le protéger contre la rétro-ingénierie.

Babel Obfuscator transforme les instructions IL d’origine de la méthode en un nouveau jeu d’instructions personnalisées, qui peut inclure diverses techniques d’obfuscation rendant le code plus difficile à soumettre à la rétro-ingénierie ou à modifier. Une fois cette nouvelle représentation du code construite, elle est chiffrée avec l’algorithme de chiffrement choisi (par exemple AES), ce qui la rend encore plus difficile à comprendre ou à modifier.

À l’exécution, lorsque l’assembly protégé est chargé en mémoire, la machine virtuelle Babel (BVM) déchiffre et exécute le code protégé. La BVM est un moteur d’exécution léger, inclus dans l’assembly obfusqué, qui fournit les fonctions nécessaires pour déchiffrer le code, l’exécuter et garantir son bon fonctionnement.

Vous déployez sur des hôtes en mode FIPS ? Comme le chiffrement du code déchiffre les corps de méthode à l’exécution au moyen du fournisseur cryptographique de la plateforme, un conteneur exécuté sur un hôte en mode FIPS sans fournisseur FIPS OpenSSL certifié peut ne pas démarrer. Voir Conformité FIPS pour la cause et le correctif.

Le chiffrement du code offre une protection élevée contre la rétro-ingénierie et le vol de propriété intellectuelle, mais il implique aussi des compromis sur les performances et la complexité de l’application ; il n’est donc pas recommandé de l’appliquer à l’ensemble du code. Il est préférable d’appliquer cette technique d’obfuscation de façon sélective aux parties les plus sensibles du code, celles qui ont besoin d’être protégées, et d’utiliser d’autres techniques d’obfuscation pour le reste. Vous trouvez ainsi un équilibre entre sécurité et performances.

Avant le chiffrement du code

Après le chiffrement du code

Le chiffrement du code de Babel est une solution entièrement managée. Autrement dit, les méthodes chiffrées ne sont pas remplacées par du code natif ciblant une plateforme donnée. Cette approche managée préserve le caractère multiplateforme du .NET Framework et permet au compilateur JIT (Just-In-Time) d’optimiser le code pour le processeur cible.

Limites du chiffrement du code

La fonctionnalité de chiffrement du code de Babel n’est pas prise en charge sur les assemblies .NET MAUI et Blazor, pour les principales raisons suivantes :

Contraintes de plateforme

• Compilation anticipée (AOT) : les plateformes comme iOS, qui sont au cœur de .NET MAUI, reposent sur la compilation AOT. Ce processus compile à l’avance le code en binaires natifs, ce qui exclut la génération ou la modification dynamique de code à l’exécution, indispensable au chiffrement et au déchiffrement du code.

Prise en charge limitée de l’espace de noms System.Reflection.Emit

• Génération d’IL restreinte : l’espace de noms System.Reflection.Emit, utilisé pour générer de l’IL dynamiquement, est peu ou pas pris en charge sur des plateformes clés comme iOS et WebAssembly (utilisé par Blazor). Comme le chiffrement du code repose souvent sur la manipulation dynamique de l’IL, cette limite complique encore l’implémentation des fonctionnalités de chiffrement dans MAUI et Blazor.

Restrictions de sécurité

• Environnements en bac à sable : MAUI et Blazor fonctionnent tous deux dans des environnements où les applications sont isolées dans un bac à sable pour des raisons de sécurité. Des plateformes comme iOS imposent des mesures de sécurité strictes qui interdisent toute modification du code à l’exécution afin d’empêcher l’exécution de code malveillant, ce qui rend le chiffrement dynamique impraticable.

• Risque d’injection de code : la génération dynamique de code qu’exigent le chiffrement et le déchiffrement présente des risques de sécurité importants, notamment des vulnérabilités potentielles d’injection de code. Les frameworks MAUI et Blazor privilégient la sécurité en évitant ces risques.

En raison de ces contraintes, .NET MAUI et Blazor ne prennent pas en charge la fonctionnalité de chiffrement du code et privilégient des pratiques de développement sûres, portables et cohérentes d’une plateforme à l’autre.

Méthodes qui ne peuvent pas être chiffrées

Dans une cible prise en charge, le chiffrement du code s’applique méthode par méthode, et quelques méthodes sont automatiquement laissées non chiffrées :

• Les constructeurs d’instance (.ctor) ne sont jamais chiffrés. C’est voulu : une instance doit être entièrement initialisée par la chaîne de ses constructeurs de base avant d’être utilisée, et cette garantie ne peut pas être préservée si le corps du constructeur est déplacé par le chiffrement du code. Notez que cela ne concerne que les constructeurs d’instance : les constructeurs statiques (.cctor) ne sont pas concernés et sont chiffrés comme n’importe quelle autre méthode.

• Les méthodes dont la signature n’est pas prise en charge sont ignorées automatiquement. Le chiffrement du code déplace le corps d’une méthode dans la machine virtuelle Babel (BVM) et le rappelle par l’intermédiaire d’un marshaleur d’arguments uniforme ; quelques formes de signature ne peuvent donc pas être exprimées et sont laissées non chiffrées :

  • MĂ©thodes gĂ©nĂ©riques : signalĂ©es par EM0003.
  • Types de retour non pris en charge : un retour ref (par rĂ©fĂ©rence), un retour de pointeur, un retour de pointeur de fonction ou un retour ref struct (de type byref) tel que Span<T>/ReadOnlySpan<T>. SignalĂ©s par EM0001.
  • Paramètres de type pointeur ou pointeur de fonction : signalĂ©s par EM0002.
  • Paramètres ref struct (de type byref) tels que Span<T>/ReadOnlySpan<T> : signalĂ©s par EM0013.

Ces limites sont inhérentes au runtime .NET : un pointeur ou un ref struct ne peut pas faire l’objet d’une conversion boxing, de sorte que le marshaleur d’arguments de la BVM ne peut pas le transporter. Tout le reste est pris en charge, y compris les paramètres ref/out/in (de tout type d’élément, y compris les structs, les enums et les types référence passés par référence), les retours de types valeur et d’instances génériques, la gestion des exceptions, les itérateurs et les méthodes async. Voir Codes d’avertissement dans l’annexe pour la liste complète des codes EM.

Les méthodes exclues pour ces raisons sont signalées pendant le build et ne font pas échouer l’obfuscation : elles sont simplement émises non chiffrées.

Considérations relatives aux performances

Le corps d’une méthode chiffrée s’exécute toujours sous forme de code compilé par le JIT, si bien que son travail interne s’effectue à une vitesse proche de celle du code natif. Ce que le chiffrement du code ajoute, c’est un petit coût de répartition par appel à chaque entrée dans une méthode chiffrée (les arguments sont marshalés vers la BVM et le résultat est marshalé en retour). Ce surcoût est négligeable pour les méthodes qui effectuent un vrai travail, mais il peut devenir prépondérant pour de très petites méthodes appelées dans des boucles extrêmement sollicitées (des millions d’appels). Pour cette raison, et pour que l’assembly reste petit et rapide, appliquez le chiffrement du code de façon sélective aux méthodes sensibles qui ont besoin d’être protégées plutôt qu’à l’ensemble du code, et évitez de chiffrer de petites méthodes utilitaires très sollicitées sur un chemin critique.

Activer le chiffrement du code

Babel Obfuscator permet d’appliquer le chiffrement du code de façon sélective à des méthodes précises au lieu de chiffrer l’ensemble du code. Cela évite les problèmes de performances que peut entraîner le chiffrement de grandes quantités de code.

Pour indiquer les méthodes à chiffrer, vous pouvez utiliser une règle XML ou l’attribut Obfuscation. Avec une règle XML, vous indiquez les noms des méthodes à chiffrer.

<Rule name="encrypt code" feature="msil encryption" exclude="false"> <Target>Methods</Target> <Pattern>ACME.Algorithms::*</Pattern> <Description>Encrypt all methods of Algorithm class.</Description> </Rule>

Vous pouvez aussi utiliser l’attribut Obfuscation pour marquer une à une les méthodes à chiffrer, en donnant au paramètre « Feature » la valeur « msil encryption ».

[Obfuscation(Feature = "msil encryption", Exclude = false)] public void ProcessData() { // Encrypted code }

Une fois le chiffrement du code activé, les méthodes sélectionnées sont chiffrées pendant l’obfuscation.

Ligne de commande

babel myapp.exe --msilencryption

Au lieu d’utiliser des règles XML ou des attributs, vous pouvez passer à l’option --msilencryption des expressions régulières qui sélectionnent les méthodes ou les types pour lesquels le chiffrement du code doit être activé. Par exemple, la commande suivante :

babel myapp.exe --msilencryption ACME.LicenseManager::.*

configure Babel pour qu’il chiffre toutes les méthodes de la classe LicenseManager de l’espace de noms ACME.

Tâche MSBuild Babel

<PropertyGroup> <MsilEncryption>true</MsilEncryption> </PropertyGroup> ​ <Babel MsilEncryption="$(MsilEncryption)" />

Babel Desktop

Sélectionnez l’assembly sur le canevas du projet puis, dans le panneau des propriétés, activez MsilEncryption dans le groupe Chiffrement du code. Vous pouvez aussi ajouter une liste d’expressions régulières pour filtrer les espaces de noms ou les classes auxquels appliquer le chiffrement du code. Laissez la liste vide si vous avez sélectionné les méthodes à chiffrer avec des règles XML ou l’attribut Obfuscation. Voir Projets d’obfuscation pour savoir comment utiliser les projets dans Babel Desktop.

Après l’exécution, la vue Résultats répertorie les méthodes chiffrées, ce qui vous permet de vérifier que le chiffrement du code a été appliqué.

Les statistiques du chiffrement du code figurent aussi dans le journal de sortie (le panneau Activité dans Babel Desktop), qui consigne chaque phase de l’obfuscation, chiffrement du code compris.

Encrypt Msil phase, elapsed time 00.579s Embedded resource: omJYi size : 13170 bytes Method statistics: 194/[ 252] resources: 76.98 % 194/[ 252] overall: 76.98 % Number of encrypted methods: 194

En examinant les statistiques du chiffrement du code dans le journal de sortie, vous vérifiez facilement que le chiffrement du code a bien été appliqué à votre code et vous évaluez le niveau de protection qu’il apporte. Vous avez ainsi la confirmation que votre code sensible a été chiffré et qu’il reste protégé contre tout accès non autorisé.

Last updated on