web-dev-qa-db-ja.com

アセンブリが特定の証明書で署名されていることをプログラムで確認するにはどうすればよいですか?

私のシナリオでは、特定のフォルダーで見つかった場合に他のプログラムを起動する1つのプログラム(exe)があります。当社の企業証明書(Verisign承認など)で署名されたプログラムのみが開始されるようにしたいと思います。基本的に、それはそれ自体と同じ証明書でのみプログラムを開始します。証明書自体は発送したくありません。

Webとシステムの名前空間を検索してきましたが、ファイルから証明書データを読み取り、それを検証し、別のファイルと照合できる明確な例は見つかりませんでした。私が見つけた最も近いものはSigntoolであり、別のexeファイルでこの検証を行うことはポイントが少ないです。ここで役立つように説明されているように、デジタル署名されたファイルは異なるため、ストロングネーミングのものは役に立たないことを私は知っています(http://blog.codingoutloud.com/2010/03/13/three-ways-to-tell-whether-an-Assembly- dl-is-strong-named /)SOのいくつかの他の例も、生データの暗号化と検証を示していますが、何らかの方法で一緒にパッケージ化されているアセンブリは示していません。

何かアイデアや提案はありますか?

20
Aaron

アセンブリの署名を確認する方法に関するコードサンプルを含むブログ投稿は次のとおりです。
http://blogs.msdn.com/b/shawnfa/archive/2004/06/07/150378.aspx

最後のコードサンプルは、アセンブリがMicrosoftによって署名されているかどうかを確認する方法を示しています。会社の証明書の証明書トークンを取得することで、同じことができます。

更新:ユーザー@Sabreはこれを次の更新で編集しましたが、その更新は他のユーザーによって拒否されました。しかし、それは非常に有効なアドバイスなので、SOは私にそれを承認させないので、私は彼/彼女の編集を再投稿しています:

編集(ありがとう、OP):これをより安全に(つまり、プログラムをより改ざんされないように)したい場合は、関連するキーで厳密に名前が付けられたプログラム内のアセンブリを参照してください。参照されているアセンブリのトークンを使用して、呼び出し元のアセンブリのトークンと比較します。 (リンクに従って)バイト配列を使用する場合は、16進数で編集および変更するだけです。

17
KristoferA

.NETアセンブリには、ストロングネーミングとAuthenticodeの2つの署名テクノロジがあります(authenticodeは、.NETアセンブリだけでなく、PEやその他のファイルの署名に使用されます)。それらはさまざまな目的で使用されます。証明書は、作成者を認証するためにのみAuthenticodeで使用されます。ストロングネーミングは、作成者をまったく認証しません。

署名の確認に加えて、証明書を検証して、特定の作成者に対して発行されたことを確認する必要があります。適切な検証は、CRL(証明書失効リスト)とOCSP(オンライン証明書ステータス)のチェックを含む複雑な手順です。

Authenticode署名の検証を実行するには、Authenticode検証コンポーネントが必要です。オプションの1つは、SecureBlackbox製品の PKIBlackbox パッケージを使用することです。このパッケージには、Authenticode検証と完全な証明書検証メカニズムが含まれています。

証明書を検証しない場合は、同じ件名、シリアル番号などで自己署名証明書を作成し、それを使用して偽造されたアセンブリに署名できるため、署名を検証する意味がまったくないことに注意してください。

ここで3つのオプションを試すことができます。

1)最初のものは、次のようにアセンブリロードを使用しています。

Assembly myDll =
    Assembly.Load("myDll, Version=1.0.0.1, Culture=neutral, PublicKeyToken=9b35aa32c18d4fb1");

次の厳密な名前(Sn.exe)コマンドを使用して、特定のアセンブリの公開鍵と公開鍵トークンの16進形式を印刷できます。

sn -Tp <Assembly>

公開鍵ファイルがある場合は、代わりに次のコマンドを使用できます(コマンドラインオプションの大文字と小文字の違いに注意してください)。

sn -tp <Assembly>

2)2番目のもの ここに記載されています 。そして、そのような問題にはp/Invokeを使用してください。

3)これを行うための3番目の、より機敏で、より複雑な方法も存在します。これはバインディングポリシーです。すでにデプロイされているアプリケーションのアップグレードを提供する必要がある場合は、これを考慮に入れることができます。アプリケーションが恩恵を受けることができる共有コンポーネントの新しいバージョンが出てきた場合、アプリケーションポリシーファイルを使用すると、既存のインストールを再コンパイルまたは置換することなく、これらの恩恵を提供できます。

この機能の詳細については、こちらをご覧ください。

http://msdn.Microsoft.com/en-us/library/aa309359%28v=vs.71%29.aspx

http://ondotnet.com/pub/a/dotnet/2003/03/17/bindingpolicy.html

3
apros

「信頼」の目的で強い名前を使う方法があると思います。マイクロソフトは、アセンブリの内容が変更されていないことを確認するために厳密な名前のみを推奨していることを理解しており、信頼のために「Authenticode」を使用することを提案しています。

ただし、ローダーアプリケーション(これらのアセンブリ/プログラムをロードするアプリケーション)が、ロードできる「アセンブリ」の暗号化されたリストを維持している場合。それは「信頼」の問題を解決しませんか?

たとえば、パッケージローダーは公開鍵でアセンブリ名を維持し、完全なアセンブリ名を介してアセンブリ/プログラムをロードできますか?

<PackageHandlers>
  <PackageHandler>
    <Package type="Package1" assembyName="SomeAssembly" publickey="d45755dbb8b44e59" />
  </PackageHandler>
</PackageHandlers>
0
Iftikhar Ali