.netアセンブリで厳密な名前は何を保護しますか?

厳密 な名前またはアセンブリシグネチャの主な目標は、 GACグローバルアセンブリキャッシュ )における一意性です。 アセンブリに基づいて、署名中に暗号化公開キーが計算され、秘密キーはアセンブリの製造元から秘密にされます。そのハッシュ関数は公開トークンであり、実際にはアセンブリの厳密な名前です。 パブリックトークンはアセンブリメタデータに格納され、アセンブリ名、バージョン、およびカルチャとペアになり、一意に識別するのに役立ちます。



このようなメカニズムが、アセンブリの一意の識別および異なるアプリケーションによる同じアセンブリの使用に非常に適していることは間違いありません。



しかし、多くの人は、厳密な名前を持つアセンブリは変更から保護されていると誤解しています。 公平に言えば、アセンブリの製造元がWebサイトなどで公開トークンまたは公開キーを公開している場合、このキーまたはトークンが使用済みアセンブリに配線されているキーと一致するかどうかを常に確認できますが、おそらく手動で確認する必要があります。 もう1つの重要なことは、多くの人が考えるように、 厳密な名前はアセンブリを変更から保護しないため、 CLRのメカニズムが正常に機能せず、変更されたアセンブリをロードしないことです。



これはどのように可能ですか? 公開トークン(公開キートークン)がアセンブリに縫い付けられているため、すべてが非常に単純です。アセンブリから削除するだけです。



しかし、このアセンブリとその厳密な名前を参照する他のアセンブリは、それをロードせず、本来のように実行されません、とあなたは言います。 はい、彼らはダウンロードしません。 また、厳密な名前で署名され、依存関係ではこのアセンブリが指定されています。 ただし、これらのアセンブリから厳密な名前またはアセンブリへのリンクを削除し、厳密な名前のない同じ名前に置き換えると、アプリケーションは正常に機能します。



確かに、uが変更のためにアセンブリにアクセスできる場合、上記のすべてが機能することに最初に注意する必要があります。 たとえば、これがWebサービスの場合、これらのアセンブリにアクセスする方法はありません。



例を見てみましょう。 会社に製品をリリースさせてください。 どんなに。 もう1つの重要なことは、製品が1つの秘密キーで署名された、したがって同じ公開トークンで署名された一定数の独自のアセンブリで構成されていることです。 製品には、サードパーティビルド、サードパーティビルド、製品に付属するコンポーネントも含まれています。 会社は、製品の機能を何らかの方法で制限することを決定しました。もちろん、制限コードと、それが機能する条件は会社のアセンブリにあります。 攻撃者は、単一のアセンブリを変更して制限を解除する必要があります。 アセンブリが署名されないように、彼はそれを修正し、厳密な名前を削除します。 それを参照する他のアセンブリが正しく機能するように、彼はそれらから署名も削除し、これらのアセンブリの依存関係を署名のないアセンブリに変更します。



おそらくこれは難しいと思いますか? いいえ、すべての学生がこれを行うことができます。 これには何が必要ですか? リフレクターとそのプラグインReflexIL



ReflexILに厳密な名前のリムーバーがあります。 とても簡単に機能します。 アセンブリを選択し、[ アセンブリディレクトリの自動スキャン ]をクリックします。 厳密な名前のアセンブリが見つかった場合、それらがリストに追加されます。 次に、「 厳密な名前を削除して参照アセンブリを更新する 」をクリックします。 これで、アセンブリから署名が削除されました。



画像



つまり 厳密な名前は、グローバルアセンブリキャッシュとの関係に加えて、アセンブリの変更からも保護されることが保証されているという事実にもかかわらず、これは実際の場合とはほど遠いものです。

したがって、変更に対する信頼できる保護として、厳密な名前に頼るべきではありません。

しかし、あなたはどうですか? 実際、これは別の記事のトピックです。 しかし、答えは明らかです。.NETの標準保護メカニズムを使用してください-難読化、マネージコードとアンマネージコードの混合の使用。



アセンブリの厳密な名前を手動で確認し、 PostSharpまたは他のAOPアプローチと組み合わせて、 呼び出す前に厳密な名前を確認する必要があることを示す属性でコード内の必要なメソッドをマークすることもできます。 そして、独自のメソッドを使用して、固定定数を持つアセンブリの厳密な名前を確認します。 この場合にのみ、検証と検証呼び出しを伴うコードの断片、および公開トークンを伴う定数を暗号化する必要があります。 または、製品を再考し、その一部をWebサービスとして取り出しますが、これは常に可能とは限りません。 次の方法で厳密な名前を手動で確認できます。

private static bool IsPublicTokenValid( byte [] tokenExpected)

{

// Retrieve token from current assembly

byte [] tokenCurrent = Assembly .GetExecutingAssembly().GetName().GetPublicKeyToken();



// Check that lengths match

if (tokenExpected.Length == tokenCurrent.Length)

{

// Check that token contents match

for ( int i = 0; i < tokenCurrent.Length; i++)

if (tokenExpected[i] != tokenCurrent[i])

return false ;

}

else

{

return false ;

}

return true ;

}








それでは、厳密な名前は何から保護しますか? 大体、何もないから。 これは、 GACで同じアセンブリの複数のバージョンを共存させることができるアセンブリを一意に識別するためのツールです。



厳密な名前はアセンブリの変更に対する保護に役立ちますか? 厳密な名前 、アセンブリのなりすましから保護することはできません 。攻撃者がアセンブリの署名を削除したり、独自のキーでアセンブリに再署名したり、この形式で配布したりすることを防ぐことはできません 。 確かに、再署名されたアセンブリには別の公開キーがあり、アセンブリの発行者の公開キーと手動で比較できます。



アセンブリ署名者を厳密な名前で使用して、アセンブリの作成者を決定することは可能ですか? 厳密な名前は、たとえばAuthenticodeによって提供されるアセンブリの信頼レベルを意味しません。



All Articles