Protecting an Algorithm with Code Encryption
A proprietary algorithm is often the most valuable thing in an assembly — and the easiest to lift straight out of a decompiler. This example uses the Babel Obfuscator NuGet package to apply MSIL Code Encryption to a scoring engine with a single MSBuild property. It is the simplest code-encryption setup: no Babel Licensing and no runtime license, because the default code encryption embeds the key in the binary and the protected application runs on its own.
To use this example you need a site license for Babel Obfuscator (Ultimate, Server or Data Center editions). The source code is available on GitHub:
git clone https://github.com/babelfornet/code-encryption-nuget-example.gitThe protected code is a proprietary scoring algorithm (src/AlgorithmApp/ScoringEngine.cs) — the
kind of intellectual property you do not want a competitor to lift out of a decompiler:
internal static class ScoringEngine
{
public static int Score(int recency, int frequency, int monetary)
{
int r = Bucket(recency, 3, 12, 30);
int f = Bucket(frequency, 2, 5, 12);
int m = Bucket(monetary, 50, 250, 1000);
return Normalize(r * 25 + f * 17 + m * 11); // vendor's secret weighting
}
// Bucket / Normalize …
}After encryption, the bodies of Score, Bucket and Normalize are gone from the IL and are
reconstructed only by the Babel Virtual Machine at runtime. The AlgorithmApp console project
encrypts the sensitive type in 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'">
<MsilEncryption>AlgorithmApp\.ScoringEngine::.*</MsilEncryption>
<BabelWarningsAsErrors>W00000</BabelWarningsAsErrors>
</PropertyGroup>MsilEncryption is a regular expression selecting which methods to encrypt — here every method on
the ScoringEngine type. Babel rewrites those method bodies into custom encrypted instructions that
only the Babel Virtual Machine can execute. This is the default
(no-<Source>) code encryption, so a Babel license is only required at build time; the protected
application runs standalone.
Building the sample in Release encrypts the three scoring methods with identical program output, and the algorithm’s IL is no longer present in the assembly. To make the encrypted code unlock only with a valid license — so removing the license check is not enough — see the licensing examples below.