このチェックリストは、アプリケーションやライブラリを PreEmptive Protection Dotfuscator で保護する際に、考慮すべき事項を確認するための 1 つの場所を提供します。 このチェックリストは随時、また、新しいバージョンの Dotfuscator に更新する都度、見直す必要があります。
開発手法
次に挙げるものは必須ではありませんが、備えているものとします。
- ソース管理システム
- ビルド アーティファクト リポジトリ(公開可能およびプライベートのビルド成果物を格納する機能)
- 開発者システムやインテグレーター システムとは異なる、継続的な統合環境
ソース ファイル
次のファイルをソース ファイルとして扱い、ソース管理システムで保持する必要があります。
- Dotfuscator 構成ファイル(例:
DotfuscatorConfig.xml
) -
増分難読化を使用した場合のみ:入力として名前変更の割り当てファイル(
Map.xml
)
上記のファイルをソースとして含める必要があります。この理由は、これらのファイルが保護の適用方法を制御するので、ビルドを再現可能とするため、また保護設定が変更された場合の追跡には重要だからです。 ほかのソース コードに対しても同様に、これらのファイルに対する変更を見直してください。
ビルド成果物
次のファイルは、プライベート ビルド成果物として扱う必要があります(または、プライベート ビルド成果物として扱われるアーカイブ ファイルに収集することができます)。
- Dotfuscator の実行時に生成されるテキスト形式のビルド出力のログ。
- Dotfuscator 関連のすべてのレポート。通常、これらのレポートは
DotfuscatorReports
またはDotfuscated
ディレクトリに含まれます。- レポートには名前変更の割り当てファイルが含まれます。このファイル名は通常、
Renaming.xml
またはMap.xml
です。 - 増分難読化を使用する場合、レポートには名前変更の出力割り当てファイルのみが含まれます。 名前変更の入力割り当てファイルは、前述のとおりソース ファイルとして処理する必要があります。
- レポートには名前変更の割り当てファイルが含まれます。このファイル名は通常、
上記のファイルの一部は、実際に適用した保護や、今後のために使用可能にする必要のある保護(監査など)の記録を保持するために重要です。 名前変更の割り当てファイルを使用して、保護されたアプリケーションのスタック トレースをデコードすることができます。 名前変更の割り当てファイルを使用すれば、名前の変更を効率的に元に戻すことができるため、秘密を守る必要があります。
プロジェクトの機密性に応じて、異なる方法でこのファイルを扱うことが必要になる場合があります。 たとえば、ビルド ログは、内部に公開して保護の検証に使用することがあります。一方、名前変更の割り当てファイルは、保護を元に戻すためにそれを使用する可能性があるため、特定の担当者しかアクセスできないようにすることがあります。
保護されていないアプリケーション バイナリまたはライブラリ バイナリを保持している場合、それらはプライベートのままにする必要があります。 保護されたアプリケーション バイナリまたはライブラリ バイナリを構成するファイルはすべて、公開可能なビルド成果物になります。
どのバイナリがどのログ ファイルまたは名前変更の割り当てファイルに対応するのかで混乱が生じないよう、ビルドごとに個別のバージョンを持つことは重要です。 たとえば、割り当てファイルはビルド間で大幅に異なることがあるため(増分難読化を使用していない場合)、スタック トレースのデコードに間違った割り当てファイルを使用すると、正しくない結果になります。
ビルド統合
継続的な統合ビルドのステップとして、Dotfuscator の保護を含める必要があります。 その際、次のことを確認してください。
-
ビルドはクリーンである。 以前のビルド結果を誤って使用することがないよう、ビルドの前に、既存のバイナリや中間ファイルはすべて削除されている。
-
プロジェクトはリリース モードでビルドされている。
-
Dotfuscator を実行し、正常に終了した。
-
ビルド サーバーおよび開発用コンピューターには、最新バージョンの Dotfuscator がインストールされている。 弊社は、保護機能について常に改善を行っています。
-
ビルド サーバーではビルド ライセンスを使用している。 一般リリース用のソフトウェアを保護するときに使用できるのは、Dotfuscator ビルド ライセンスのみです。 これはビルド出力を調べれば確認できます。
-
構成ファイルの生成を無効にしている。
-
署名が期待どおりに行われた。 Dotfuscator 構成で指定された証明書は、エンド ユーザーが受け取るバイナリの署名に使用されたものと一致している必要があります。
-
カスタマー フィードバック プログラムを既定の設定
有効
のままにしておく(お客様およびお客様の会社に差し支えない場合)。 Dotfuscator は実行時に、このプログラムを介して、機能の利用状況およびサマリー プロジェクトのデータを弊社のサーバーに送信することができる。これは、新機能および既存の機能を開発するために役立っています。
製品の構成
プロジェクトに合うように Dotfuscator 構成を調整することは重要です。 詳しい手順については、保護の強化を参照してください。 随時、このページを見直し、現在推奨されるすべての強化機能を使用していることを確認してください。
保護されたプロジェクトのテスト
保護されたアプリケーションに対していくつかのテストを実施する必要があるかもしれませんが、毎回リリース前には、保護されたアプリケーションが機能テストを受けることは非常に重要です。 アプリケーションのコードは時間が経つにつれて変更が加えられるので、コード変更によって保護設定に問題が発生しないように、機能テストを行ってください。 非常にまれであることを期待しますが、バグにより、同じアプリケーションの後続の 2 つの保護が異なる動作をする可能性があります。
保護されたアプリケーションの定期処理パフォーマンス テストをお勧めします。 これにより、アプリケーションに加えた変更が原因で、アプリケーションの保護を最初に構成したときには存在しなかったパフォーマンス問題が生じることを回避できます。 プロジェクトの構成に重要な変更を加えた場合には、パフォーマンス テストを実施することをお勧めします。
以下のセクションでは、主要な機能を説明するとともに、機能ごとに必要に応じて機能とパフォーマンスに関する考慮事項について説明します。
名前の変更(機能)
名前の変更による難読化は、難読化の最も一般的な形態であり、高い有効性がありますが、シンボルの名前が変更され、そのシンボルへの参照の名前は変更されない場合、アプリケーションの機能を壊す可能性があります。 ほとんどの場合、Dotfuscator は、シンプルなリフレクション、標準 XAML、またはマニフェスト ファイルなどにある名前ベースの参照を自動的に識別し、参照の名前を自動的に変更することができます。 しかし、より複雑な参照は静的に分析することができないため、名前を変更できません。 Dotfuscator は、そのような参照を識別し、適切なシンボルを名前変更の対象から除外するよう試みますが、これをすべてのシナリオで行うことは不可能です。
そのため、名前変更が適用された後、機能テストのためのプロジェクト スケジュールを立てることは重要です。 また、どれくらい積極的にシンボルの名前を変更するかを決定することも重要です。 既定では、Dotfuscator は比較的安全な設定を使用します。
使用される名前の文字集合や長さなどの追加オプションを設定することで、機能の問題のリスクは増大しますが、名前の変更の強度を高めることもできます。
アプリケーションが比較的簡単な方法でリフレクションを使用している場合は、リフレクション クラスを名前変更するのも妥当かもしれません。
制御フロー(パフォーマンス)
ほとんどの場合、、制御フローの難読化は低リスクです。 既定では難読化が最高の設定でオンになっています。 ただし、コードのパフォーマンスを要求される領域では、制御フローの難読化はパフォーマンスを低下させる可能性があるため、それに関して懸念がある場合は、パフォーマンスをテストするか、またはコードのパフォーマンスを要求される領域を制御フローの難読化の対象から除外してください。
制御フローのもう 1 つの考慮事項は、特定の難読化変換が (ほかの .NET ランタイムでは問題ないのに)Mono で正しく実行しないことです。 これが懸念される場合は、Dotfuscator の設定で Mono 互換の変換を使用するようにしてください。
文字列の暗号化(パフォーマンス)
文字列の暗号化による難読化は、既定では無効になっており、コードの特定の領域に対して有効にする必要があります。 文字列の暗号化は、文字列へのアクセス方法を変更するため、特に、タイトなループで文字列が検索される場合には、パフォーマンスに影響を及ぼします。
パフォーマンスを要求される領域がなく、GUI 指向が強いアプリの場合、文字列の暗号化はコードベース全体にわたって有効にすることができるでしょう。 そうでないアプリの場合、パフォーマンスを要求される領域での文字列の暗号化は避けてください。しかし、機密性の高い文字列へ注目が集まるのを避けるためには、広範囲で文字列の暗号化を有効にしてください。
文字列の暗号化を広範囲で有効にした場合は、アプリケーションのパフォーマンスをテストしてパフォーマンスに変化があるかどうかを確認してください。
チェック(機能)
Dotfuscator のすべてのチェックは、アプリケーションのライフサイクル内の特定の時刻および場所、具体的に言うと、チェックを差し込むよう Dotfuscator を構成したあらゆるところで実行されます。 通常、チェックを差し込むのに適しているのは、アプリケーションのスタートアップかその近くはもちろんのこと、アプリケーションのライフサイクル全体のほかの場所、特に、コードの機密性が高い領域の周辺も適しています。
Dotfuscator のすべてのチェックは、チェックがトリガーされたときに構成できる、動作の共通セットを共有しています。 後述のように、それぞれの動作には、あらかじめの考慮がいくらか必要です。
最初に、チェックは、トリガーされたときのカスタム動作を有効にするために、アプリケーション内のメソッドを呼び出す(またはフィールドを設定する)ことができます。 カスタム動作は、アプリケーションの動作を変更したり、サード パーティ製のアナリティクス プラットフォームを使用したりするために使用されます。 カスタム動作を使用するには、アプリケーション コードを変更または追加する必要があります。 したがって、これは開発者がコードを変更できる場合のみのオプションです。
次に、Dotfuscator は、定義済みの操作(アプリケーションの終了など)を自動的に実行するコードを差し込むことができます。 チェックによってトリガーされる動作(組み込みまたはカスタム)に関する重要な考慮事項は、動作の妥当性です。 たとえば、デバッグ チェックがトリガーされた場合は、アプリケーションを終了するか、またはアプリケーションの機能セットを制限することが適切です。 けれども、本番アプリケーションにデバッガーをアタッチできることが正当なシナリオが存在する可能性があるため、すべてのアプリケーション データをワイプすることは、おそらく適切ではありません。
属性を使用してチェックを構成する場合は、チェック属性ページを参照してください。
使用されていないコードの除去(機能)
Dotfuscator は、アプリケーションから使用されていないコードを除去することもできます。 これはバイナリ サイズを減らすことと、攻撃対象領域を減らすことに役立ちます。 除去は、アプリケーションのエントリ ポイントを識別し、それらのポイントからアクセスできるすべてのコードを静的に分析することにより、自動的に動作します。 しかし、動的なリフレクションなどがあったりするため、静的な分析で、使用されているコードをすべて検出できるとは限りません。 そのため、除去によってアプリケーションの機能が壊れる可能性があります。ですから、除去が適用された後、機能テストのためのプロジェクト スケジュールを立てることは重要です。
また、どれくらい積極的にコードを除去するかを決定することも重要です。 名前の変更と同様に、ライブラリ モードは除去に影響し、パブリックのコード要素を除去しません。 Dotfuscator には除去の積極性の度合いを増減できる追加オプションもあります。しかし、除去の積極性の度合いを増やせば機能の問題のリスクも増大します。
除去は既定では無効になっています。Dotfuscator のセットアップの一環として、各種設定が希望どおりになっているかを確認することは重要です。
リンク(機能)
リンクは、複数の入力を結合して 1 つの出力にする方法です。 これにより、配置シナリオを簡素化できるうえ、攻撃者がアプリケーションの構造を若干理解しづらくなるようにすることができます。
リンクは既定では無効になっているので、使用するには有効にして構成する必要があります。
通常、難読化後にさらにパッケージ化するアプリケーションにはリンクは必要ありません (たとえば、Xamarin Android アプリが .apk ファイルなどの Android パッケージにパッケージ化される場合など)。
ウォーターマーク
ウォーターマークは、攻撃者が簡単には見抜けないように、アプリケーションの構造にカスタム文字列を埋め込む方法です。 アプリケーションからウォーターマークを抽出して、特定のビルドを識別することができます。
ウォーターマークは構成エディターの PreMark セクションで構成することができます。既定ではウォーターマークは無効になっています。
リリース準備
- チェックリストの手順に従っているか、あるいは、手順または機能を適用しない理由がわかり、記録されているかを確認する。
- 保護されたビルドが機能テストに合格しているかを確認する。
- レポート、割り当てファイル、およびビルド ログがすべてアーカイブされているかを確認する。
上記の手順では、アーカイブされた名前変更の割り当てファイルを使用して難読化されたスタック トレースを変換する など、リリースされた製品で問題を診断することもできます。