可以使用強命名程序集來驗證程序集作者嗎?
我一直在閱讀 MSDN 中的正確文章,Strong-Named Assemblies和相關的 Stack Overflow 問題,Checking an assembly for a strong name。
- 可以在多大程度上驗證強名稱程序集以避免篡改?
- 是否可以使用強命名來驗證程序集作者?
第一個問題出現在閱讀 CSharp411 文章*.NET Assembly FAQ – Part 3 – Strong Names and Signing*之後,其中提到了這一點,以及使用強名稱的其他問題:
“***無法停止完全替換。***強名稱無法阻止黑客刪除強名稱簽名,惡意修改您的程序集,用他自己的密鑰重新簽名,然後將他的程序集冒充為您的。”
第二個問題旨在找出強命名和其他簽名方案(例如Authenticode )之間的區別。同一篇 MSDN 文章提到了早期狀態:
“但是請注意,強名稱本身並不意味著像數字簽名和支持證書所提供的那樣的信任級別。 "
我是否試圖將強命名用於比創建它時更多的用途?創建強命名是為了避免名稱衝突還是一種新的“GAC DLL Hell”?
當您使用基於您創建的私鑰的強名稱簽署程序集時,這具有以下好處:
- 強名稱通過向程序集添加公鑰令牌和數字簽名來保證程序集身份的唯一性。
- 強名稱可以與公鑰匹配,以證明程序集來自具有該公鑰的發布者,並且僅來自該發布者。
- 強名稱提供強完整性檢查。通過 .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 完成的,如下所示。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 ); }請注意,預設情況下,這不適用於使用 .NET 3.5 SP1 或更高版本(具有強名稱繞過功能)的應用程序。可以通過將設置添加到其配置文件來為您的應用程序禁用此功能。但是當然,任何對該配置文件具有讀/寫訪問權限的攻擊者都可以推翻您的決定。