多層防御:すべてのレイヤーを 1 回のビルドで
強力な保護は、1 つの仕掛けだけでは得られません。レイヤーを重ねることで得られます。このサンプルでは、1 つの小さなアセンブリに対して Babel Obfuscator の NuGet パッケージのすべての保護を有効にします。そのため、Ultimate の完全な構成を 1 つのプロジェクトファイルで確認し、自分のアプリケーションに合わせて調整できます。
このサンプルを使用するには、Babel Obfuscator のサイトライセンス(Ultimate、Server、Data Center のいずれかのエディション)が必要です。ソースコードは GitHub で公開しています。
git clone https://github.com/babelfornet/defense-in-depth-nuget-example.gitアプリケーションは小さな機能ゲート(src/LicenseGate/FeatureGate.cs)で、文字列、数値の重み、配列、分岐ロジックという、各レイヤーの保護対象にあたるものをひととおり含んでいます。
internal static class FeatureGate
{
private static readonly int[] Weights = { 3, 7, 11, 13, 17, 19, 23, 29, 31, 37 };
private static readonly string Pepper = "d3f3ns3-1n-d3pth-pepper";
public static GateReport Evaluate(string edition, int tokens, double budget)
{
bool allowed = edition is "PRO" or "ENTERPRISE" && tokens > 0 && budget >= 100.0;
double score = 0.0;
for (int i = 0; i < Weights.Length; i++)
score += Weights[i] * (tokens + 1) * 0.5;
return new GateReport(edition, allowed, Math.Round(score / budget, 4), Digest(edition, tokens));
}
// Digest …
}LicenseGate コンソールプロジェクトは、Release でレイヤーを重ねます。
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<!-- Rename & restructure -->
<FlattenNamespaces>true</FlattenNamespaces>
<OverloadedRenaming>true</OverloadedRenaming>
<VirtualFunctions>true</VirtualFunctions>
<!-- Hide data -->
<StringEncryption>stream</StringEncryption>
<ValueEncryption>int32=true;int64=true;single=true;double=true;array=true;true</ValueEncryption>
<ResourceEncryption>true</ResourceEncryption>
<!-- Obscure logic -->
<ControlFlowObfuscation>if=true;switch=true;case=true;chain=true;true</ControlFlowObfuscation>
<ControlFlowIterations>3</ControlFlowIterations>
<DynamicProxy>external=true;true</DynamicProxy>
<!-- Detect & deter runtime attacks -->
<TamperingDetection>true</TamperingDetection>
<DebuggingProtection>true</DebuggingProtection>
<SuppressIldasm>true</SuppressIldasm>
<!-- Strip metadata -->
<CleanAttributes>true</CleanAttributes>
<SealClasses>true</SealClasses>
<BabelWarningsAsErrors>W00000</BabelWarningsAsErrors>
</PropertyGroup>各プロパティが 1 つのレイヤーを追加します。リネームと名前空間のフラット化は意図を隠し、文字列暗号化、値の暗号化、リソース暗号化はデータを隠し、制御フローと動的プロキシはロジックを隠します。改ざん検出とデバッグ保護は実行時の攻撃を抑止し、メタデータの整理は実行中のアプリケーションに不要なものを除去します。パッケージはビルド専用の依存関係(PrivateAssets=all)であるため、これらがアプリ自身の依存関係グラフに入り込むことはなく、SDK の後続の処理はすでに保護されたアセンブリに対して行われます。
サンプルを Release でビルドすると、プログラムの出力は変わらないまま、上記のすべてが適用されます。結果をデコンパイラーで開き、Debug ビルドと比較して違いを確認してください。これはコードセキュリティの強化の指針に沿ったものです。この構成から始めて、不要なレイヤーを外してください。