22

MSDN の適切な記事、厳密な名前のアセンブリ、および関連するスタック オーバーフローの質問、Checking an assembly for a strong name を読んでいます。

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

最初の質問は、CSharp411 の記事.NET Assembly FAQ – Part 3 – Strong Names and Signingを読んだ後に発生します。この記事では、厳密な名前を使用することの他の問題の中で、これについて言及しています。

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

2 番目の質問は、厳密な名前付けと、たとえばAuthenticodeなどの他の署名スキームとの違いを見つけることを目的としています。同じ MSDN の記事で、初期状態について言及されています。

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

作成された目的よりもはるかに多くの目的で厳密な命名を使用しようとしていますか? 厳密な名前付けは、名前の衝突や新しい種類の「GAC DLL 地獄」を回避するためだけに作成されたものですか?

4

5 に答える 5

23

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

  • 厳密な名前は、公開鍵トークンとデジタル署名をアセンブリに追加することにより、アセンブリの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.5SP1より前のバージョンの.NETFrameworkで実行している限り、攻撃者によって厳密な名前が削除された場合や、レジストリ。次のコードは、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を使用して行われます。StrongNameSignatureVerificationEx APIの使用法は非常に複雑です。適切な説明については、このブログエントリを参照してください。

// 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 );
}

これは、強力な名前バイパス機能を備えた.NET3.5SP1以降を使用するアプリケーションではデフォルトで機能しないことに注意してください。構成ファイルに設定を追加することにより、アプリケーションでこの機能を無効にすることができます。ただし、もちろん、その構成ファイルへの読み取り/書き込みアクセス権を持つ攻撃者は、決定を覆す可能性があります。

于 2008-12-15T19:40:04.190 に答える
12

Authenticode は、証明書の検証をサード パーティの認証局に依存しています。厳密な名前付けは、自己署名証明書のように機能し、そのように扱うことができます。標準のデジタル署名を使用しますが、問題は、アセンブリ作成者の公開キーが実際に有効であることを確認することにあります。作成者から信頼できるチャネルを介して個別に取得し、そのチャネルを信頼する場合、はい、自己署名証明書と同じように検証できます。

厳密な名前の秘密鍵が作成者によって安全に保管されていることが確実であり、作成者の公開鍵を知っている限り、それが改ざんされていないことを確認できます (デジタル署名された電子メールが改ざんされていないことを確認できる範囲で)。ところで、誤解しないでください。引用は完全に真実であり、攻撃者は簡単にアセンブリを辞任したり、既存の署名を削除したりできます。ただし、結果として得られるアセンブリには、元の署名と照合できる **異なる* デジタル署名が含まれます (元の公開キーを持っている場合)。

この場合、自己署名証明書に似ています。何らかの形で作成者の公開鍵を確認できる場合は、権限を確認できます。ただし、認証局に依存する Authenticode とは異なり、公開鍵を配布する簡単なシステム定義の方法はありません。

于 2008-12-15T18:27:17.020 に答える
1

厳密な名前はバージョン管理に役立ち、 Code Access Security Editの信頼レベルの設定に使用できると思いますが、アセンブリが信頼できる人または特定の作成者によって作成されていることを確認するためにそれらを使用することはできません。@RoadWarrior からのコメントと、この質問に対する @RoadWarrior の回答を参照してください。

アセンブリに厳密な名前を付けても、改ざん防止にはなりません。
編集: @RoadWarrior と @divo からのコメントを参照してください。アプリケーションがアセンブリの作成者からの元の秘密キーをチェックし、厳密な名前の検証を強制している場合、私のステートメントは正しくありません。ただし、攻撃者がアプリケーション内のすべてのアセンブリにアクセスできる場合、および/または CLR から無料で提供されているように、すぐに使用できる厳密な名前検証を使用している場合は、私が言ったことを支持します。

これは、断固たる攻撃者によって覆される可能性があります。

少し前に、厳密な名前とセキュリティに関する議論を読んで、私たちが生成するアセンブリについては、Authenticode が、アセンブリが信頼できるソースからのものであることを顧客に保証するより良い方法であると確信しました。

于 2008-12-15T18:40:32.797 に答える
0

アセンブリの整合性をチェックする場合は、公開キー トークンのチェック (上記の「HTTP 410」の回答を参照) と、StrongNameSignatureVerificationEx ( https://docs.microsoft.com/de-de/dotnetを使用したチェック) を行う必要があります。 /framework/unmanaged-api/strong-naming/strongnamesignatureverificationex-function )。StrongNameSignatureVerificationExの結果と出力パラメーターpfWasVerifiedの両方が true でなければなりません。すべてのアセンブリに対して1 つの署名キー ファイル (.snk) を使用するだけです。

BabelFor.Net などの .NET アセンブリ難読化ツールの方がよいでしょう。それらの多くには、改ざん防止チェックが組み込まれています。

乾杯

于 2020-10-22T03:02:47.980 に答える