アセンブリの厳密な名前付けを使用してアセンブリの作成者を確認できますか? 質問する

アセンブリの厳密な名前付けを使用してアセンブリの作成者を確認できますか? 質問する

私はMSDNで適切な記事を読んできましたが、厳密な名前のアセンブリ関連するStack Overflowの質問、アセンブリの厳密な名前のチェック

  1. 改ざんを防ぐために、厳密な名前のアセンブリをどの程度まで検証できますか?
  2. 厳密な名前付けを使用してアセンブリの作成者を確認することは可能ですか?

CSharp411の記事を読んだ後に最初の疑問が浮かびます.NET アセンブリ FAQ – パート 3 – 厳密な名前と署名では、厳密な名前の使用に関するその他の問題の中でも、この点について言及しています。

完全な交換は止められない。強力な名前では、ハッカーが強力な名前の署名を削除し、悪意を持ってアセンブリを変更し、独自のキーで再署名して、自分のアセンブリをあなたのアセンブリとして偽装することを防ぐことはできません。

2番目の質問は、強力な命名と他の署名スキームとの違いを見つけることを意図しています。例えば、オーセンティコード先ほど言及した同じ MSDN の記事には次のように書かれています。

ただし、強力な名前自体は、たとえばデジタル署名やサポート証明書によって提供されるようなレベルの信頼を意味するものではないことに注意してください。

強力な名前付けを、それが作成された目的以上に使用しようとしていますか? 強力な名前付けは、名前の衝突や新しい種類の「GAC DLL 地獄」を回避するためだけに作成されたのでしょうか?

ベストアンサー1

作成した秘密キーに基づいて厳密な名前でアセンブリに署名すると、次のような利点があります。

  • 厳密な名前は、アセンブリに公開キー トークンとデジタル署名を追加することで、アセンブリの ID の一意性を保証します。
  • 厳密な名前を公開キーと照合することで、アセンブリがその公開キーを持つ発行元からのみ発行されたことを証明できます。
  • 厳密な名前は、強力な整合性チェックを提供します。.NET Framework セキュリティ チェックに合格すると、アセンブリの内容が最後にビルドされてから変更されていないことが保証されます。

厳密な名前付けを使用してアセンブリの作成者を確認することは可能ですか?

はい、上で説明したように、厳密な名前付けによりアセンブリの最新作成者。ただし、元の作成者は検証されません。攻撃者がアセンブリの厳密な名前を置き換えた場合、確認できるのは、そのアセンブリの最新の作成者ではなかったということだけです。攻撃者が厳密な名前を削除した場合、作成者の検証はまったく実行できなくなります。

改ざんを防ぐために、厳密な名前のアセンブリをどの程度まで検証できますか?

次の C# コードは、厳密な名前を適用したときにアセンブリに書き込まれた公開キー トークンが攻撃者によって改ざんされていないことを確認します。改ざんは回避できませんが、一部の種類の改ざんは検出できます。以下のメソッドは、公開キー トークンを含むバイト配列を受け取り、それをアセンブリの実際のトークンと比較します。この手法が効果的であるためには、選択した難読化ツールで公開キー トークンを含む文字列を暗号化し、使用時にその場でのみ復号化する必要があることに注意してください。また、このコードは内部でリフレクションを使用しているため、動作させるには FullTrust アクセス許可が必要であることにも注意してください。

// Check that public key token matches what's expected.
private static bool IsPublicTokenOkay_Check(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;
}

.NET 3.5 SP1 より前のバージョンの .NET Framework を実行している限り、攻撃者によって厳密な名前が削除された場合や、レジストリで厳密な名前のチェックが無効になっている場合に、厳密な名前の署名の検証を強制することもできます。次のコードは、NativeMethods という別のクラスの静的メソッドの呼び出しを示しています。ここで検証が強制されます。

// Check that this assembly has a strong name.
private bool IsStrongNameValid_Check()
{
    byte wasVerified = Convert.ToByte(false); 
     byte forceVerification = Convert.ToByte(true);
    string assemblyName = AppDomain.CurrentDomain.BaseDirectory + 
                          AppDomain.CurrentDomain.FriendlyName; 
    return NativeMethods.CheckSignature(assemblyName, 
                                        forceVerification, 
                                        ref wasVerified);
}

実際の署名検証は、以下に示すようにP/Invokeを使用して行われます。強力な名前署名検証ExAPIは非常に複雑です。適切な説明については、このブログ記事

// P/Invoke to check various security settings
// Using byte for arguments rather than bool, 
// because bool won't work on 64-bit Windows!
[DllImport("mscoree.dll", CharSet=CharSet.Unicode)]
private static extern bool StrongNameSignatureVerificationEx(string wszFilePath, 
                                                             byte fForceVerification, 
                                                             ref byte pfWasVerified);

// Private constructor because this type has no non-static members
private NativeMethods()
{
}

public static bool CheckSignature(string assemblyName, 
                                  byte forceVerification, 
                                  ref byte wasVerified)
{
    return StrongNameSignatureVerificationEx(assemblyName, 
                                             forceVerification, 
                                             ref wasVerified );
}

ただし、.NET 3.5 SP1以降を使用するアプリケーションでは、デフォルトでは動作しません。厳密な名前バイパス機能可能ですこの機能を無効にするアプリケーションの設定ファイルに設定を追加することで、アプリケーションを保護できます。ただし、もちろん、その設定ファイルへの読み取り/書き込みアクセス権を持つ攻撃者は、決定を覆すことができます。

おすすめ記事