.NET Assembly Plugin Security

后端 未结 6 919
梦谈多话
梦谈多话 2020-12-08 12:17

I have used the following code in a number of applications to load .DLL assemblies that expose plugins.

However, I previously was always concerned with functionality

6条回答
  •  囚心锁ツ
    2020-12-08 12:37

    1) strong name the assembly with a certain key.

    • you do not have to put it in the GAC
    • you can re-use a key to sign more than one assembly
    • when you re-use the key, you get the same "public key" on each signed assembly

    2) on load, check that the assembly has been strong named with the key you're expecting

    • You can store the public key as a binary file, an embedded resource, or use the existing public key of the executing assembly
    • this last way may not be the best way as you may want to differentiate assemblies signed with the "plugin" key from those signed with a regular key)

    Example:

    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;
    

    note: code has not been tested or compiled, may contain syntax errors.

提交回复
热议问题