Skip to Content
Nouvelle version 12 disponible 🎉
ObfuscatorPackage NuGetProtection des secrets

Protéger les secrets avec le chiffrement des chaînes et des valeurs

Presque toutes les applications sont livrées avec des secrets dans leur code : clés API, points de terminaison, chaînes de connexion, paramètres de licence, nombres « magiques » et tables de correspondance. Un décompilateur les lit en quelques secondes. Cet exemple utilise le package NuGet Babel Obfuscator pour retirer ces littéraux de l’assembly livré grâce au chiffrement des chaînes et au chiffrement des valeurs et des tableaux, sans modifier une seule ligne de code.

Pour utiliser cet exemple, vous avez besoin d’une licence de site pour Babel Obfuscator (édition Ultimate, Server ou Data Center). Le code source est disponible sur GitHub :

git clone https://github.com/babelfornet/secret-protection-nuget-example.git

Le projet console SecretApp référence le package NuGet Babel Obfuscator (utilisé uniquement à la génération) et active les deux couches de chiffrement en Release :

<ItemGroup Condition="'$(Configuration)' == 'Release'"> <PackageReference Include="Babel.Obfuscator" Version="12.0.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> </ItemGroup> <PropertyGroup Condition="'$(Configuration)' == 'Release'"> <StringEncryption>stream</StringEncryption> <ValueEncryption>int32=true;int64=true;single=true;double=true;array=true;true</ValueEncryption> <ControlFlowObfuscation>if=true;switch=true;case=true;chain=true;true</ControlFlowObfuscation> <BabelWarningsAsErrors>W00000</BabelWarningsAsErrors> </PropertyGroup>

L’algorithme de chaînes stream déplace chaque littéral de chaîne dans une table chiffrée, tandis que le chiffrement des valeurs et des tableaux retire de l’IL les constantes numériques et les tableaux en ligne. Dans les deux cas, le déchiffrement a lieu à la demande, à l’exécution : le programme se comporte exactement comme avant, alors que les constantes disparaissent du binaire. Régler BabelWarningsAsErrors sur W00000 transforme en erreur un build en mode d’évaluation, de sorte qu’un binaire non protégé ne puisse jamais être livré par accident.

Les secrets eux-mêmes se trouvent dans src/SecretApp/Secrets.cs :

internal static class Secrets { // Strings -> removed by String Encryption (stream) public static readonly string ApiKey = "DEMO-API-KEY-0000-1111-2222-3333-4444-5555"; public static readonly string ServiceEndpoint = "https://api.internal.example.com/v3/ingest"; public static readonly string ConnectionString = "Server=db.internal;Database=Orders;User Id=svc;Password=__DEMO_PLACEHOLDER__;"; // Numbers -> removed by Value Encryption public static readonly int ApiPort = 8443; public static readonly double RiskThreshold = 0.8734; // Lookup table -> removed by Array Encryption public static readonly int[] RolloutBuckets = { 12, 47, 63, 88, 91, 128, /* … */ 8192, 9001 }; }

L’exemple met aussi en évidence un détail important : les secrets sont déclarés static readonly, et non const. Une valeur const est inscrite dans les métadonnées de l’assembly et recopiée à chaque endroit où elle est utilisée ; elle survit donc à l’obfuscation et reste lisible. Un champ static readonly, lui, est affecté par une instruction ldstr/ldc que le chiffrement des chaînes et des valeurs réécrit. Générer l’exemple en Release et rechercher dans les deux assemblies confirme la différence : la clé API, le point de terminaison et la chaîne de connexion sont présents dans le build Debug et absents du build Release, la sortie du programme étant identique.

Last updated on