Un seul fichier obfusqué : fusion des dépendances
Livrer une application avec les DLL de ses dépendances offre une plus grande surface à un attaquant, et ces bibliothèques ne sont généralement pas obfusquées du tout. Cet exemple utilise le package NuGet Babel Obfuscator pour fusionner un assembly référencé dans l’hôte, internaliser ses types publics et obfusquer le résultat : vous livrez ainsi un seul fichier autonome, sans bibliothèques éparses et lisibles.
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/single-file-merge-nuget-example.gitPaymentCore est une bibliothèque de classes ordinaire dotée d’une API publique
(src/PaymentCore/PaymentProcessor.cs), que Checkout utilise comme n’importe quelle dépendance :
// PaymentCore (the dependency)
public sealed class PaymentProcessor
{
public PaymentProcessor(decimal feeRate) => _feeRate = feeRate;
public decimal Charge(decimal amount) => amount + Math.Round(amount * _feeRate, 2);
}
// Checkout (the host)
var processor = new PaymentProcessor(feeRate: 0.029m);
Console.WriteLine(processor.Charge(100.00m)); // 102.90Après le build, PaymentProcessor est un type interne et renommé à l’intérieur de Checkout.dll :
il n’y a pas de PaymentCore.dll à livrer. Le projet console Checkout référence la bibliothèque et
la fusionne au moyen de deux propriétés MSBuild en Release :
<ItemGroup>
<ProjectReference Include="..\PaymentCore\PaymentCore.csproj" />
</ItemGroup>
<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'">
<MergeAssemblies>true</MergeAssemblies>
<Internalize>true</Internalize>
<StringEncryption>hash</StringEncryption>
<BabelWarningsAsErrors>W00000</BabelWarningsAsErrors>
</PropertyGroup>MergeAssemblies fusionne les assemblies référencés dans la sortie, et Internalize rend internal
les types publics fusionnés, afin qu’ils puissent être renommés et ne fassent plus partie d’aucune
surface publique. Le package Babel exécute la fusion avant les
étapes ultérieures du SDK, à savoir la résolution des dépendances, le découpage (trimming) et le
regroupement en fichier unique, et préserve la cohérence de dotnet publish en mettant à jour le
fichier .deps.json et l’ensemble des fichiers publiés.
Générer l’exemple en Release produit un seul fichier Checkout.dll (PaymentCore.dll n’est plus
présent, car il a été fusionné), et l’application s’exécute à partir de ce seul fichier avec une
sortie identique. Si vous préférez conserver une dépendance sous la forme d’un bloc chiffré opaque
plutôt que de fusionner ses types, utilisez EmbedAssemblies à la place.