Skip to Content
New release 12 available 🎉
LicensingExternal Encrypted Code

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.git

ReportTool 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.dll

The four combinations make the two-factor gate visible:

Licensepremium.eil deliveredResult
StandardnoPremium blocked
PremiumnoPremium blocked — feature not delivered
StandardyesPremium blocked — not licensed
PremiumyesPremium 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.

Last updated on