最新バージョンのWindowsで使用するためにMicrosoft によって定義された共通言語基盤(CLI)のアセンブリは、配置、バージョン管理、およびセキュリティに使用されるコンパイル済みコード ライブラリです。プロセス アセンブリ ( EXE ) とライブラリ アセンブリ ( DLL ) の 2 種類があります。プロセス アセンブリは、ライブラリ アセンブリで定義されたクラスを使用するプロセスを表します。CLI アセンブリにはCILのコードが含まれており、これは通常、CLI 言語から生成され、実行時にジャストインタイム コンパイラによってマシン語にコンパイルされます。.NET Framework実装では、このコンパイラは共通言語ランタイム(CLR)の一部です。
アセンブリは 1 つ以上のファイルで構成できます。コード ファイルはモジュールと呼ばれます。アセンブリには複数のコード モジュールを含めることができます。また、コード モジュールの作成には異なる言語を使用できることから、複数の異なる言語を使用してアセンブリを作成することは技術的に可能です。ただし、 Visual Studio では1 つのアセンブリで異なる言語を使用することはサポートされていません。
アセンブリ名
アセンブリの名前は4つの部分から構成されます
- 短い名前。Windows では、これは拡張子のないPortable Executable (PE) ファイルの名前です。
- カルチャ。これは、アセンブリのロケールの RFC 1766 識別子です。一般に、ライブラリ アセンブリとプロセス アセンブリはカルチャに依存しません。カルチャはサテライト アセンブリにのみ使用してください。
- バージョン。これは、メジャー、マイナー、ビルド、リビジョンの 4 つの値で構成されるドット付きの数字です。
- 公開鍵トークン。これは、アセンブリの署名[1]に使用される秘密鍵に対応する公開鍵の64ビット ハッシュです。署名されたアセンブリは、厳密な名前を持つと言われています。
公開キー トークンは、アセンブリ名を一意にするために使用されます。したがって、2 つの厳密な名前のアセンブリが同じ PE ファイル名を持つ場合でも、CLI はそれらを異なるアセンブリとして認識します。Windowsファイル システム( FAT32およびNTFS ) は PE ファイル名のみを認識するため、同じ PE ファイル名 (ただし、カルチャ、バージョン、または公開キー トークンが異なる) を持つ 2 つのアセンブリが同じ Windows フォルダーに存在することはできません。この問題を解決するために、CLI は実行時に単一のフォルダーとして扱われるが、実際にはネストされたファイル システム フォルダーを使用して実装される GAC (グローバル アセンブリ キャッシュ) を導入します。
クラッカーがアセンブリを別のものに見せかけて偽装しようとするスプーフィング攻撃を防ぐために、アセンブリは秘密キーで署名されます。 意図したアセンブリの開発者は秘密キーを秘密に保持するため、クラッカーはそれにアクセスすることも、簡単に推測することもできません。 したがって、クラッカーはアセンブリを別のものに偽装することができず、変更後に正しく署名する可能性がありません。 アセンブリに署名するには、アセンブリの重要な部分のハッシュを取得し、そのハッシュを秘密キーで暗号化する必要があります。 署名されたハッシュは、公開キーとともにアセンブリに格納されます。 公開キーは、署名されたハッシュを復号化します。 CLR は、厳密な名前のアセンブリを読み込むときに、アセンブリからハッシュを生成し、これを復号化されたハッシュと比較します。 比較が成功した場合、ファイル内の公開キー (つまり、公開キー トークン) が、アセンブリの署名に使用された秘密キーに関連付けられていることを意味します。 つまり、アセンブリ内の公開キーはアセンブリ発行者の公開キーであり、スプーフィング攻撃は防止されます。
アセンブリバージョン
CLIアセンブリにはバージョン情報を持たせることができるため、共有アセンブリによって発生するアプリケーション間の競合のほとんどを排除できます。[2]ただし、これによってアセンブリ間のバージョン競合がすべて排除されるわけではありません。[3]
アセンブリと CLI セキュリティ
CLIコード アクセス セキュリティは、アセンブリと証拠に基づいています。証拠はアセンブリから推測されるものであれば何でも構いませんが、通常はアセンブリのソースから作成されます。つまり、アセンブリがインターネットやイントラネットからダウンロードされたか、ローカル マシンにインストールされたか (アセンブリが別のマシンからダウンロードされた場合は、GAC 内のサンドボックス化された場所に格納されるため、ローカルにインストールされたものとして扱われません) に関係なく作成されます。アクセス許可はアセンブリ全体に適用され、アセンブリはカスタム属性を通じて必要な最小限のアクセス許可を指定できます ( CLI メタデータを参照)。アセンブリが読み込まれると、CLR はアセンブリの証拠を使用して、1 つ以上のコード アクセス権限のアクセス許可セットを作成します。次に、CLR は、このアクセス許可セットにアセンブリで指定された必要なアクセス許可が含まれているかどうかを確認します。
CLI コードは、コード アクセス セキュリティ要求を実行できます。つまり、コール スタック内のすべてのメソッドのすべてのアセンブリに指定されたアクセス許可がある場合にのみ、コードは特権アクションを実行します。1 つのアセンブリにアクセス許可がない場合、セキュリティ例外がスローされます。
CLI コードは、コール スタックから権限を取得するためにリンク デマンドを実行することもできます。この場合、CLR は指定された権限について、コール スタックの最上位にある 1 つのメソッドのみを調べます。ここで、スタック ウォークスルーはコール スタック内の 1 つのメソッドにバインドされ、CLR はコール スタック内の他のすべてのメソッドに指定された権限があると想定します。アセンブリは、メタデータと MSIL ファイルの組み合わせです。
衛星アセンブリ
一般に、アセンブリにはカルチャに依存しないリソースを含める必要があります。アセンブリをローカライズする場合 (たとえば、異なるロケールに異なる文字列を使用する場合)、サテライト アセンブリ (特別なリソースのみのアセンブリ) を使用する必要があります。名前が示すように、サテライトはメイン アセンブリと呼ばれるアセンブリに関連付けられます。そのアセンブリ (たとえば、lib.dll) には、ニュートラル リソース (Microsoft は International Englishとしていますが、米国英語であることを意味します) が含まれます。各サテライトには、関連付けられているライブラリの名前に .resources が付加されます (たとえば、lib.resources.dll)。サテライトには非ニュートラル カルチャ名が付けられますが、これは既存の Windows ファイル システム (FAT32 および NTFS) では無視されるため、1 つのフォルダーに同じ PE 名のファイルが複数存在する可能性があります。これは不可能なので、サテライトはアプリケーション フォルダーの下のサブフォルダーに格納する必要があります。たとえば、英国英語のリソースを含むサテライトの CLI 名は「lib.resources Version=0.0.0.0 Culture=en-GB PublicKeyToken=null」、PE ファイル名は lib.resources.dll となり、en-GB というサブフォルダーに保存されます。
サテライトは、 という CLI クラスによってロードされますSystem.Resources.ResourceManager。開発者は、リソースの名前とメイン アセンブリ (ニュートラル リソースを含む) に関する情報を提供する必要があります。ResourceManager クラスは、マシンのロケールを読み取り、この情報とメイン アセンブリの名前を使用して、サテライトの名前とそれを含むサブフォルダーの名前を取得します。ResourceManagerその後、サテライトをロードして、ローカライズされたリソースを取得できます。
アセンブリの参照
C# コンパイラの /reference フラグを使用して、実行可能コード ライブラリを参照できます。
アセンブリの遅延署名
共有アセンブリには、アプリケーション間で共有される可能性のあるアセンブリを一意に識別するための厳密な名前を付ける必要があります。厳密な名前付けは、公開キー トークン、カルチャ、バージョン、および PE ファイル名で構成されます。アセンブリが開発目的で使用される可能性がある共有アセンブリの場合、厳密な名前付け手順には公開キーの生成のみが含まれます。その時点では秘密キーは生成されません。アセンブリが展開されるときにのみ生成されます。
会議の言語
アセンブリは、中間言語である CIL コードで構築されます。フレームワークは、内部的に CIL (バイトコード) をネイティブアセンブリ コードに変換します。「Hello World」と印刷するプログラムがある場合、メソッドに相当する CIL コードは次のようになります。
. method private hidebysig static void Main ( string [] args ) cil managed { . entrypoint . custom instance void [ mscorlib ] System . STAThreadAttribute ::. ctor () = ( 01 00 00 00 ) // コード サイズ 11 (0xb) . maxstack 1 IL_0000 : ldstr "Hello World" IL_0005 : call void [ mscorlib ] System . Console :: WriteLine ( string ) IL_000a : ret } // メソッドの終了 Class1::Main
CIL コードは文字列をスタックにロードし、WriteLine 関数を呼び出して戻ります。
参照
参考文献
- ^ 「.NET アセンブリに厳密な名前を付ける」。2012 年 2 月 24 日時点のオリジナルよりアーカイブ。2007 年3 月 29 日閲覧。
- ^ Truche, Philippe (2008 年 8 月 12 日). 「.NET アセンブリ バージョン管理ライフサイクル」。2008 年 10 月 24 日時点のオリジナルよりアーカイブ。2008年9 月 21 日閲覧。
- ^ Pierson, Harry (2008年9月17日). 「DLR Namespace Change Fire Drill」。2008年11月1日時点のオリジナルよりアーカイブ。 2008年9月21日閲覧。
