Skip to Content
Nouvelle version 12 disponible 🎉

Algorithmes standard

Babel Obfuscator est fourni avec trois algorithmes de chiffrement des chaînes intégrés : XOR, HASH et STREAM. Tous trois sont autonomes (ils déchiffrent sans aucune donnée externe), si bien que choisir entre eux revient à un compromis entre le temps de chargement, la taille de sortie et la difficulté de récupérer les chaînes. Cette page décrit chaque algorithme et la manière de l’activer ; le tableau comparatif en fin de page résume les différences.

Algorithme XOR

L’algorithme XOR que Babel Obfuscator utilise pour le chiffrement des chaînes est un algorithme simple, qui applique un XOR entre les caractères des chaînes en ligne et une clé entière aléatoire. Cette méthode a l’avantage d’offrir un déchiffrement plus rapide et un temps de chargement plus court que les autres algorithmes de chiffrement.

Ligne de commande

Pour configurer l’algorithme de chiffrement XOR pour votre application depuis la ligne de commande de Babel Obfuscator, utilisez la commande suivante :

babel myapp.exe --string xor

Cette commande demande à Babel d’appliquer le chiffrement XOR aux chaînes en ligne de l’exécutable de votre application, en tirant parti de la simplicité et de la rapidité de l’algorithme XOR pour obfusquer les chaînes.

Tâche MSBuild Babel

Configurer l’algorithme XOR pour le chiffrement des chaînes de votre projet avec la tâche MSBuild Babel est simple. Ajoutez à votre fichier de projet MSBuild un groupe de propriétés et une tâche Babel avec la configuration propre à la méthode de chiffrement XOR :

<PropertyGroup> <StringEncryption>xor</StringEncryption> </PropertyGroup> <Babel StringEncryption="$(StringEncryption)" />

Avec cette configuration, Babel Obfuscator applique l’algorithme de chiffrement XOR aux chaînes de votre projet, ce qui renforce leur sécurité et les rend plus résistantes à la falsification et à la rétro-ingénierie.

Algorithme HASH

L’algorithme HASH utilisé par Babel Obfuscator repose sur des tables de hachage adressées par des clés entières. Il compresse et chiffre à la fois les données des chaînes, ce qui peut réduire la taille totale qu’elles occupent dans le fichier. Toutefois, comme les données compressées doivent être déchiffrées à l’exécution, il peut avoir une incidence sur le temps de chargement de l’application. Par rapport à l’algorithme XOR, qui applique un XOR entre les caractères des chaînes en ligne et une clé entière aléatoire, l’algorithme HASH protège mieux contre les attaques visant à déchiffrer les chaînes, au prix d’un temps de chargement plus long.

Ligne de commande

Pour configurer le chiffrement HASH avec le CLI de Babel Obfuscator, utilisez cette commande :

babel myapp.exe --string hash

Tâche MSBuild Babel

Pour activer le chiffrement HASH avec la tâche MSBuild de Babel, définissez la propriété StringEncryption comme suit :

<PropertyGroup> <StringEncryption>hash</StringEncryption> </PropertyGroup> <Babel StringEncryption="$(StringEncryption)" />

Ainsi intégré, l’algorithme HASH garantit que les chaînes de votre projet sont correctement protégées pendant le build.

Algorithme STREAM Ultimate

L’algorithme STREAM est l’option moderne de chiffrement authentifié des chaînes de Babel Obfuscator. Il chiffre chaque chaîne individuellement avec un algorithme de chiffrement robuste, conforme aux standards du secteur, et vérifie une balise d’authentification avant de la renvoyer. STREAM possède ainsi quatre propriétés que les algorithmes plus anciens n’ont pas :

  • Déchiffrement différé, chaîne par chaîne. Une chaîne n’est déchiffrée que la première fois qu’elle est réellement utilisée, et le résultat est mis en cache. Contrairement à HASH, STREAM ne déchiffre jamais l’ensemble des chaînes à l’avance : une image mémoire n’expose donc que les quelques chaînes que l’application a déjà utilisées, et il n’existe aucun moment où toutes les chaînes se trouvent en clair en mémoire.
  • Intégrité et aléa propre à chaque chaîne. La balise d’authentification détecte toute falsification des données chiffrées, et deux chaînes identiques donnent des octets chiffrés différents, ce qui met en échec l’analyse de fréquence et d’égalité à laquelle un simple schéma XOR donne prise.
  • Une clé jamais stockée en ligne. La clé n’est pas conservée sous forme de littéral à côté de l’appel de déchiffrement : un désobfuscateur automatisé doit donc exécuter le code réel pour récupérer une chaîne, au lieu de simplement lire une clé placée à côté de l’appel.
  • Un déchiffrement lié au contexte d’appel de votre code. Exécuter le déchiffreur ne suffit pas : il ne renvoie une chaîne qu’à un appelant qui s’exécute dans l’assembly protégé lui-même (ou dans le runtime .NET, afin que LINQ/PLINQ et les chemins asynchrones continuent de fonctionner). La méthode habituelle par laquelle un désobfuscateur automatisé extrait d’une seule commande toutes les chaînes chiffrées, à savoir lier un délégué directement au déchiffreur et l’invoquer par lots depuis son propre assembly auxiliaire, est mise en échec. Cela ne rend pas les chaînes impossibles à récupérer par une analyse dynamique complète, mais supprime la voie peu coûteuse de l’extraction en masse et oblige un attaquant à faire exécuter votre code réel.

Le déchiffreur est écrit entièrement en code managé, sans aucune dépendance envers le fournisseur cryptographique de la plateforme. STREAM fonctionne donc sans modification de .NET Framework 4.x (et 2.0) à .NET 10, sur Mono/Xamarin et, parce qu’il n’utilise pas Reflection.Emit, dans les applications NativeAOT et découpées (trimming). Il n’est pas non plus concerné par le problème de démarrage lié à FIPS qui peut toucher les algorithmes reposant sur la plateforme.

STREAM est autonome : comme XOR et HASH, il déchiffre sans aucune donnée externe. Comme il s’agit d’un schéma purement local, il ne peut pas rendre les chaînes impossibles à récupérer par une analyse dynamique complète (aucun schéma autonome ne le peut), mais il rend l’extraction automatisée comme la rétro-ingénierie manuelle bien plus coûteuses qu’avec XOR et HASH.

Plateformes et frameworks pris en charge

Comme le déchiffreur est entièrement managé et n’utilise ni Reflection.Emit, ni code dynamique, ni parcours de pile, ni fournisseur cryptographique de la plateforme, STREAM a été vérifié sur toute la gamme .NET et sur mobile :

  • De .NET Framework 2.0 / 4.x à .NET 10, .NET Core et Mono / Xamarin.
  • Applications découpées (ILLink) et NativeAOT : le déchiffreur injecté et sa table de chaînes incorporée survivent à l’édition des liens, et le code se compile à l’avance, sans JIT.
  • Android et iOS : vérifié de bout en bout avec de vraies applications obfusquées sur l’émulateur Android et le simulateur iOS, y compris avec des builds Release entièrement découpés, où les chaînes sont déchiffrées à l’exécution et où aucun texte en clair ne subsiste dans l’assembly placé dans le paquet. .NET MAUI repose sur ces mêmes runtimes (net*-android / net*-ios), et la même prise en charge s’applique donc. L’AOT complet sur appareil iOS est couvert par la compatibilité NativeAOT mentionnée ci-dessus.

Sur mobile, appliquez STREAM dans une passe limitée au chiffrement des chaînes, afin que les noms de types et de membres restent intacts pour la couche d’interopérabilité Java / Objective-C :

babel MyApp.dll --stringencryption stream --notypes --nomethods --nofields --noproperties --noevents --noparameters --novirtualmembers

Lorsque Babel s’exécute comme étape MSBuild dans un build .NET Android / iOS / MAUI, insérez-le après la compilation de l’assembly de l’application et avant l’empaquetage, afin que l’application empaquetée contienne l’assembly obfusqué.

Ligne de commande

Pour appliquer le chiffrement STREAM depuis la ligne de commande :

babel myapp.exe --string stream

Tâche MSBuild Babel

Pour activer le chiffrement STREAM avec la tâche MSBuild de Babel, définissez la propriété StringEncryption comme suit :

<PropertyGroup> <StringEncryption>stream</StringEncryption> </PropertyGroup> <Babel StringEncryption="$(StringEncryption)" />

STREAM fonctionne avec les autres protections. Il peut être combiné avec le chiffrement du code (MSIL) et la protection contre la falsification sur le même assembly.

Protection contre la falsification et réécriture après le build. La protection contre la falsification inscrit un hachage d’intégrité de l’image obfusquée. Toute étape qui réécrit l’assembly après Babel, notamment une publication découpée ou NativeAOT, qui émet de nouveau l’assembly managé, modifie ces octets et fait échouer le contrôle dès le démarrage. Ce comportement est inhérent à la protection contre la falsification et ne dépend pas de l’algorithme de chiffrement des chaînes (il concerne XOR, HASH et STREAM de la même façon) : activez la protection contre la falsification pour les builds qui ne sont pas ensuite découpés ni réécrits par l’AOT, et appuyez-vous sur le chiffrement des chaînes (et sur le chiffrement du code) pour les sorties découpées ou AOT.

Comparer les algorithmes

Les trois algorithmes intégrés sont autonomes (ils déchiffrent sans aucune donnée externe), si bien que choisir entre eux revient à un compromis entre le temps de chargement, la taille de sortie et la difficulté de récupérer les chaînes.

XORHASHSTREAM
ChiffrementXOR en ligne avec une clé entière par chaîneTable compressée, chiffrée avec l’algorithme de la plateformeChiffrement authentifié par chaîne, conforme aux standards du secteur
Chaînes conservées sous forme de littérauxOui (brouillées sur place)NonNon
Modèle de déchiffrementPar chaîne, à chaque accèsAnticipé : toute la table est déchiffrée à la première utilisationDifféré : chaque chaîne à sa première utilisation, puis mise en cache
Texte en clair conservé en mémoireUne chaîne à la foisToute la table, pendant toute l’exécutionUniquement les chaînes réellement utilisées
Balise d’intégrité par chaîne——Oui
Des chaînes identiques sont chiffrées différemmentNonNonOui
Refuse le déchiffrement hors contexte (invocation par délégué)——Oui
Clé de déchiffrementEn ligne, à côté de l’appelStockée dans l’en-tête du blobJamais en ligne : reconstruite à l’exécution et imbriquée dans le flux de contrôle
Déchiffreur entièrement managé (sans fournisseur cryptographique de la plateforme ; compatible avec FIPS)NonNonOui
Taille de sortie relativeLa plus grande (les littéraux restent dans l’assembly)La plus petite (un seul blob compressé)Entre XOR et HASH
Coût relatif à l’exécutionLe plus faibleFaible, mais payé d’avance pour toutes les chaînesPlus élevé par chaîne, payé uniquement pour les chaînes utilisées

Lequel choisir.

  • XOR : le plus rapide et le plus léger, mais aussi le plus faible. Les chaînes chiffrées restent sous forme de littéraux dans l’assembly et une clé par chaîne se trouve à côté de chaque appel, si bien qu’un outil automatisé peut les récupérer en une seule passe. Choisissez-le lorsque le temps de chargement compte plus que la protection.
  • HASH : supprime les littéraux et regroupe l’ensemble des chaînes dans un seul blob compressé et chiffré (la plus petite sortie), avec une protection de la table contre la falsification. En contrepartie, toute la table est déchiffrée de manière anticipée à la première utilisation, de sorte que chaque chaîne reste en clair en mémoire jusqu’à la fin de l’exécution, et son déchiffreur dépend du fournisseur cryptographique de la plateforme (voir la remarque sur FIPS).
  • STREAM : le plus robuste des trois face à l’analyse statique comme à l’analyse dynamique. Il offre un chiffrement authentifié par chaîne, sans déchiffrement global anticipé ni clé en ligne, et un seul déchiffreur entièrement managé, qui se publie sans modification avec NativeAOT et le découpage et n’est pas concerné par FIPS. Le coût de déchiffrement par chaîne est plus élevé, mais vous ne le payez que pour les chaînes que l’application utilise réellement, et à aucun moment l’ensemble des chaînes ne se trouve en clair en mémoire. Préférez STREAM pour .NET moderne, pour les déploiements AOT, découpés ou FIPS, et partout où la résistance à l’extraction en masse des chaînes compte le plus.
Last updated on