.net - 可以使用强命名程序集来验证程序集作者吗?

标签 .net security assemblies strongname

我一直在阅读 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”?

    最佳答案

    当您使用基于您创建的私钥的强名称签署程序集时,这具有以下好处:

  • 强名称通过向程序集添加公钥 token 和数字签名来保证程序集身份的唯一性。
  • 强名称可以与公钥匹配,以证明程序集来自具有该公钥的发布者,并且仅来自该发布者。
  • 强名称提供强完整性检查。通过 .NET Framework 安全检查可确保程序集的内容自上次生成后未更改。

  • 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/

    相关文章:

    c# - 如何使用 Ninject 设置可选的方法拦截?

    .net - 在 %temp% 中读取文件时出现随机 UnauthorizedAccessException

    c# - 当 c# 中存在歧义时,始终使用定义的命名空间

    c# - 在 Windows 7 上调用 IPrincipal.IsInRole

    c# - 如何防止 .NET 应用程序从 GAC 加载/引用程序集?

    asp.net-mvc - 无法加载 Antlr3.Runtime,HRESULT : 0x80131040

    .net - SAML 身份提供商的示例 .NET 代码

    linux - Linux 用户帐户中是否有一段 secret 数据?

    php - 使用 PHP 保护获取的数据

    visual-studio-2010 - Visual Studio 2010:针对更高框架版本的引用程序集