解説

インサイド .NET Framework [改訂版]

第2回 アセンブリのアイデンティティ

吉松 史彰
2003/07/02

Page1 Page2 Page3 Page4 Page5

厳密名がついたアセンブリとそうでないアセンブリ

 名前付けに関していうと、アセンブリには2種類ある。厳密名がついているかいないかの違いである。上記のコードではAssemblyKeyName属性に何か設定したのかどうかということだ。何か設定したうえでコンパイルが通っていれば、アセンブリのメタデータには公開キーが含まれている。公開キーを含む名前のことを厳密名といっている。

 厳密名が付いているかいないかというのは大変重要な違いだ。というのも、厳密名が付いていないアセンブリには次のような制限があるからだ。

  • 複数のアプリケーションで共有できない*1
  • バージョン管理の対象にならない
  • セキュリティ・チェックができない

 いずれの機能も、.NET Frameworkの大きな利点である。これらがほぼすべて使えなくなってしまうのだ。いうまでもなく、特別な理由がない限り、アセンブリには厳密名をつけなければならない。厳密名をつけなければ、何のために.NET Framework上で開発を行うのか、その理由がなくなってしまうのだ。

 上記のセキュリティ・チェックとは、デジタル署名によるファイルの改ざん防止機能を指している。詳しくは後述するが、厳密名を付けると、アセンブリにRSAデジタル署名が付けられる。また、マニフェストの中に、署名で使った秘密キーに対応する公開キーが埋め込まれる。そのため、あとで(実行時や導入時に)これを使って署名を検証すれば、ファイルの改ざんをチェックすることができる。昨今.NETウイルスと称するものが話題になったが、この機能が正しく動作している限り、厳密名がついているアセンブリにウイルスを直接感染させることは不可能なのだ*2

*1 まったく不可能ではないが、あまりお勧めされない方法でしか共有できない。

*2 このデジタル署名は証明書ではないので、公開キーだけを見てもそれがだれのものなのかを判別することはできない。ただし、アセンブリには従来のActiveXコントロールと同様に、Authenticodeテクノロジを使って証明書を埋め込むこともできる。

秘密キー/公開キー・ペアの作成

 アセンブリに厳密名をつけるには、AssemblyKeyName属性(とコマンドライン引数)に秘密キーと公開キーのペアを渡す必要がある。このペアは、厳密名ツール(sn.exe)で作成する。

 sn.exeに“-k”オプションを付けて、ファイル名を指定すると、キー・ペアを作成してファイルに出力することができる。

% sn.exe -k fumiakiy.snk

 キー・ペアはファイルとしてそのまま保存しておくのはよくない。次のように“-i”オプションでファイルとCSPコンテナを指定して、適切な場所に保管した方がいいだろう。

% sn.exe -i fumiakiy.snk CspContainer

 CspContainerという名前のコンテナが作成されて、その中にキー・ペアが格納される。これが済んだら、先ほどのファイルは削除してしまった方がいい。このコンテナはデフォルトのものなので、実際には次のフォルダに配置されている。

C:\Documents and Settings
    \All Users
      \Application Data
        \Microsoft
          \Crypto
            \RSA
              \MachineKeys

 前述のAssemblyKeyName属性(または/keynameオプション)には、このコンテナ名(上記の例ではCspContainer)を指定する。

なぜキー・ペアはファイルではいけないのか

 “-k”で作成したファイルも、それをさらに“-i”でコンテナにインストールしたものも、結局は両方ともHDD上のファイルだ。それなのにわざわざ“-i”でコンテナにインストールする理由はなんだろうか。

 このコンテナは、正確にはCSPコンテナと呼ばれている。CSPは「Cryptographic Service Provider」の略で、Windowsに標準で含まれているAPI/SPI(Service Provider Interface)である。sn.exeはWindowsにデフォルトで含まれるRSA方式のプロバイダを使ってキー・ペアを生成する。さらにそれを格納するコンテナ機能も、このRSAプロバイダが提供している(上記のフォルダにファイルとして保存する機能を持っている)。

 CSPコンテナは標準のもの以外にもいくつか存在する。最もよく耳にするのが、Windows 2000でサポートされているスマート・カードだ。スマート・カードのIC部分を保管場所として利用する。もちろん自作することもまったく不可能ではないので、USBメモリに格納するCSPプロバイダを書くこともできるだろう。

 厳密名付きのアセンブリならウイルスとは無縁というセキュリティ機能も、このキー・ペアが盗まれないことを前提に成り立つ仮定である。例えば、「b77a5c561934e089」という値はMicrosoft製を示す公開キー・トークン(後述)だ。.NET Frameworkの構成要素であるSystem.Xmlアセンブリはこの公開キー・トークンと対応する秘密キーで署名されている。もしもこの秘密キーが盗まれてしまったら、Microsoft以外の誰かが次の名前のアセンブリを作ることができてしまう。

System.Xml, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

 この、Microsoft謹製でないSystem.Xmlアセンブリがマシンにインストールされたらどうなるだろうか。恐らく大半のアプリケーションが動作しなくなるだろう。そのような事態を防ぐために、Microsoftはキー・ペアを何らかのハードウェアに保管して(もちろんそれに対応するCSPプログラムを開発したのだろう)、それを数人しかアクセスできない金庫にしまっているらしい。それくらい厳重に管理しなければならないものなのである。

 ディスク上のファイルであっても、厳重に管理することは不可能ではないだろう。CFのようなリムーバブル・メディアにファイルとして保管しておくのもいいかもしれない。だが、一般にファイルは簡単にアクセスできてしまう。コピーを作るのも容易だ。中古パソコンからデータが復元されて問題になったこともある。ファイルとして保管しておくよりも、より抽象的な「コンテナ」に保管しておく方が推奨される理由はここにある。もちろんデフォルトでは結局ファイルになってしまうのだが、それでも一元管理できるという点ではファイルよりもいいだろう。

 なお、何らかの事情で(あるいは何も考えていなくて)キー・ペアをファイルとして持っている場合には、AssemblyKeyNameではなくAssemblyKeyFileを使えば、ファイルから厳密名をつけることができる。この場合は、次のようにファイル名を書くことになる。

[assembly: System.Reflection.AssemblyKeyFile("fumiakiy.snk")]

 また、al.exeでは“/keyname”の代わりに、“/keyfile”をつけることができる。繰り返すが、これらは推奨されない。


 INDEX
  解説 インサイド .NET Framework [改訂版]
  第2回 アセンブリのアイデンティティ
    1.アセンブリの名前
  2.厳密名とアセンブリ
    3.署名のないアセンブリ
    4.遅延署名したアセンブリを試す
    5.アセンブリの名前の参照
 
インデックス・ページヘ  「解説:インサイド .NET Framework [改訂版]」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間