我一直在阅读 MSDN 中的正确文章,Strong-Named Assemblies和一个相关的 Stack 溢出问题 Checking an assembly for a strong name .
阅读 CSharp411 文章 .NET Assembly FAQ – Part 3 – Strong Names and Signing 后出现第一个问题,其中提到了这一点,以及使用强名称的其他问题:
"Cannot Stop Full Replacement. Strong names cannot prevent a hacker from removing the strong name signature, maliciously modifying your assembly, re-signing it with his own key, and then passing off his assembly as yours."
第二个问题旨在找出强命名和其他签名方案(例如 Authenticode)之间的区别。 .同一篇 MSDN 文章提到了早期状态:
"Note, however, that strong names in and of themselves do not imply a level of trust like that provided, for example, by a digital signature and supporting certificate."
我是否试图将强命名用于比创建它时更多的用途?创建强命名是为了避免名称冲突还是一种新的“GAC DLL Hell”?
最佳答案
当您使用基于您创建的私钥的强名称签署程序集时,这具有以下好处:
Is it possible to use strong-naming to verify an assembly author?
是的,如上所述,强命名可以验证程序集的 最新作者。但它并没有验证原作者。如果攻击者替换了您的程序集的强名称,那么可以验证的是您不是该程序集的最新作者。如果他删除强名称,则根本无法进行作者验证。
To which extent can a strong-named assembly be verified to avoid tampering?
以下 C# 代码验证攻击者未篡改在应用强名称时写入程序集的公钥 token 。它不能避免篡改,但它可以检测到某些类型的篡改。下面的方法接受一个包含您的公钥 token 的字节数组,并将其与程序集的实际 token 进行比较。请注意,要使此技术有效,您选择的混淆器应加密包含您的公钥 token 的字符串,并且仅在使用时动态解密它。还要注意,您需要拥有 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 相当复杂 - 要获得适当的解释,请参阅 this blog entry .// 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 或更高版本的应用程序,这将不起作用,它具有 strong name bypass feature。 .有可能disable this feature为您的应用程序添加一个设置到其配置文件。但是当然,任何对该配置文件具有读/写访问权限的攻击者都可以覆盖您的决定。
关于.net - 可以使用强命名程序集来验证程序集作者吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/369248/