微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – .NET程序集插件安全性

我在许多应用程序中使用以下代码来加载暴露插件的.DLL程序集.

然而,我以前一直关心功能,而不是安全性.

我现在打算在一个web应用程序上使用这个方法,可以由除我以外的其他组织使用,我想确保该功能的安全性是最新的.

private void Loadplugins(string pluginsDirectory)
{
    List<IPluginFactory> factories = new List<IPluginFactory>();

    foreach (string path in Directory.GetFiles(pluginsDirectory,"*.dll"))
    {
        Assembly assembly = Assembly.LoadFile(path);
        foreach (Type type in assembly.GetTypes())
        {
            IPluginEnumerator instance = null;
            if (type.GetInterface("IPluginEnumerator") != null)
                instance = (IPluginEnumerator)Activator.CreateInstance(type);
            if (instance != null)
            {
                factories.AddRange(instance.EnumerateFactories());
            }
        }
    }

    // Here,I would usually collate the plugins into List<ISpecificPlugin>,etc.
}

我有以下几个关切:

>这个函数读取整个目录,并不关心它加载的程序集,而是加载它们.在使用Assembly.LoadFile()加载程序集之前,有没有办法检测程序集是否是一个有效的.NET程序集?
>什么样的异常处理应该添加函数中以防止程序集的初始化停止我的代码
>如果我想拒绝汇编有权执行以下操作:读/写文件,读/注册注册表等,我该怎么做?

有什么其他安全问题我应该担心吗?

编辑:请记住,我希望任何人能够编写一个插件,但我仍然希望安全.

解决方法

1)用一个特定的键命名装配体.

>你不必把它放在GAC里
>您可以重新使用键来签署多个程序集
>当您重新使用密钥时,您将在每个签名的程序集上获得相同的“公钥”

2)加载时,请使用您期望的密钥检查程序集是否被强命名

>您可以将公钥存储为二进制文件,嵌入式资源,
或使用执行程序集的现有公钥
>最后一个方法可能不是最好的方法,你可能想要区分程序集
使用常规键签名的“插件”键签名)

例:

public static StrongName GetStrongName(Assembly assembly)
{
    if(assembly == null)
        throw new ArgumentNullException("assembly");
    AssemblyName assemblyName = assembly.GetName();

    // get the public key blob
    byte[] publicKey = assemblyName.GetPublicKey();
    if(publicKey == null || publicKey.Length == 0)
       throw new InvalidOperationException( String.Format("{0} is not strongly named",assembly));

    StrongNamePublicKeyBlob keyBlob = new StrongNamePublicKeyBlob(publicKey);

    // create the StrongName
    return new StrongName(keyBlob,assemblyName.Name,assemblyName.Version);
}


// load the assembly:
Assembly asm = Assembly.LoadFile(path);
StrongName sn = GetStrongName(asm);

// at this point
// A: assembly is loaded
// B: assembly is signed
// C: we're reasonably certain the assembly has not been tampered with
// (the mechanism for this check,and it's weaknesses,are documented elsewhere)

// all that remains is to compare the assembly's public key with 
// a copy you've stored for this purpose,let's use the executing assembly's strong name
StrongName mySn = GetStrongName(Assembly.GetExecutingAssembly());

// if the sn does not match,put this loaded assembly in jail
if (mySn.PublicKey!=sn.PublicKey)
    return false;

注意:代码未经测试或编译,可能包含语法错误.

原文地址:https://www.jb51.cc/csharp/96008.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐