Feature as an External Encrypted File
Ship a premium feature as encrypted code that lives outside the application and is unlocked only when the customer also holds a license that grants it.
Babel Obfuscator can strip the encrypted body of a method into a separate binary file with the
.eil extension instead of embedding it in the assembly (see
External Code Files). That file can be
deployed independently — for example, delivered together with a license the moment a customer
upgrades. This example combines the two: the premium code is an external .eil file, and both
the file and a valid Babel license granting the feature are required to run it.
Code Example
git clone https://github.com/babelfornet/external-encrypted-code-console-example.gitReportTool is a console application with a free Standard report and a Premium analysis. The
Premium code is encrypted into premium.eil; LicenseGenerator mints either a Standard or a
Premium license.
External Encryption
The premium method sets a source but not internal, so Babel writes its encrypted body to
an external premium.eil file:
[Obfuscation(Feature = "msil encryption:source=premium;password=Pr3m!um-R3port-K3y", Exclude = false)]
public static string Analyze(int[] data)
{
double mean = data.Average();
double variance = data.Select(x => (x - mean) * (x - mean)).Sum() / data.Length;
return $"Premium analysis: mean={mean:0.00}, variance={variance:0.00}, stddev={Math.Sqrt(variance):0.00}";
}Babel emits premium.eil next to the intermediate assembly. A short MSBuild target copies it to
the output folder so it can be deployed with — or deliberately withheld from — the application:
<Target Name="CopyBabelExternalFiles" AfterTargets="Build">
<ItemGroup>
<BabelEilFiles Include="$(IntermediateOutputPath)*.eil" />
</ItemGroup>
<Copy SourceFiles="@(BabelEilFiles)" DestinationFolder="$(OutDir)"
SkipUnchangedFiles="false" Condition="'@(BabelEilFiles)' != ''" />
</Target>Two License-Gated Hooks
For external code the BVM calls two hooks: one to obtain the encrypted stream, and one for the password. This example gates both on a valid license, so neither the file alone nor the license alone is sufficient:
// Returns the .eil stream only when a valid license grants the feature.
[Obfuscation(Feature = "msil encryption get stream")]
internal static Stream? GetSourceStream(string source)
{
if (!HasFeature(source))
return null; // Not licensed for this feature.
var path = Path.Combine(FeaturesDirectory, source + ".eil");
return File.Exists(path) ? File.OpenRead(path) : null; // Feature file not delivered.
}
// Returns the password carried by the license.
[Obfuscation(Feature = "msil encryption get password")]
internal static string GetSourcePassword(string source)
{
var license = Validate();
var field = license.Fields.FirstOrDefault(f => f.Name == source)
?? throw new InvalidOperationException($"License does not grant source '{source}'.");
return field.Value.Decrypt(Secrets.FieldSecret);
}HasFeature returns true only when the validated license carries a field with the feature
name, which the generator adds for a Premium license:
if (premium)
{
string encrypted = Secrets.PremiumPassword.Encrypt(Secrets.FieldSecret);
builder = builder.WithField(Secrets.PremiumSource, encrypted);
}Running It
# Build in Release — Babel encrypts Premium.Analyze into premium.eil.
dotnet build src/ReportTool/ReportTool.csproj -c Release
# Mint a Premium license (add --standard for a Standard one).
dotnet run --project src/LicenseGenerator
# Deliver BOTH the license and the external code, then run.
cp ReportTool.lic src/ReportTool/bin/Release/net8.0/
dotnet src/ReportTool/bin/Release/net8.0/ReportTool.dllThe four combinations make the two-factor gate visible:
| License | premium.eil delivered | Result |
|---|---|---|
| Standard | no | Premium blocked |
| Premium | no | Premium blocked — feature not delivered |
| Standard | yes | Premium blocked — not licensed |
| Premium | yes | Premium analysis runs |
When either factor is missing, the BVM reports no code source premium stream and the Standard
report keeps working on its own.
Delivering protected code as a separate file is a natural fit for feature-based and add-on
licensing: the base application is one download, and each paid feature is a small .eil file
shipped alongside the license that unlocks it. The vendor can revoke a feature by simply not
renewing the license that grants it.
keys.pem and the passwords in the sample are for demonstration only. In production the license
is issued by the vendor or the Babel Licensing Service,
and the RSA private key is kept offline.