How to prevent others from using my .Net assembly?

2019-01-17 04:49发布

问题:

I have an assembly which should not be used by any application other than the designated executable. Please give me some instructions to do so.

回答1:

You can sign the assembly and the executable with the same key and then put a check in the constructor of the classes you want to protect:

public class NotForAnyoneElse {
  public NotForAnyoneElse() {
    if (typeof(NotForAnyoneElse).Assembly.GetName().GetPublicKeyToken() != Assembly.GetEntryAssembly().GetName().GetPublicKeyToken()) {
      throw new SomeException(...);
    }
  }
}


回答2:

In .Net 2.0 or better, make everything internal, and then use Friend Assemblies

http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx

This will not stop reflection. I want to incorporate some of the information from below. If you absolutely need to stop anyone from calling, probably the best solution is:

  1. ILMerge the .exe and .dll
  2. obfuscate the final .exe

You could also check up the call stack and get the assembly for each caller and make sure that they are all signed with the same key as the assembly.



回答3:

100% completely impossible without jumping through some hoops.

One of the perks of using the .NET is the ability to use reflection, that is load up an assembly and inspect it, dynamically call methods, etc. This is what makes interop between VB.NET and F# possible.

However, since your code is in a managed assembly that means that anybody can add a reference to your code and invoke its public methods or load it using reflection and call private methods. Even if you 'obfuscate' your code, people will still be able to use reflection and invoke your code. However, since all the names will be masked doing anything is prohibitavely difficult.

If you must ship your .NET code in a fashion that prevents other people from executing it, you might be able to NGEN your binary (compile it to x86) and ship those binaries.

I don't know the specifics of your situation, but obfuscation should be good enough.



回答4:

You could also look at using the Netz executable packer and compressor.

This takes your assemblies and your .exe file and packs them into a single executable so they're not visible to the outside world without a bit of digging around.

My guess is that this is sufficient to prevent access for most .net programmers.

A big benefit of the .netz approach is that it does not require you to change your code. Another benefit is that it really simplifies your installation process.



回答5:

You should be able to make everything internally scoped, and then use the InternalsVisibleTo Attribute to grant only that one assembly access to the internal methods.



回答6:

The Code Access Security attribute that @Charles Graham mentions is StrongNameIdentityPermissionAttribute



回答7:

As some people have mentioned, use the InternalsVisibleTo attribute and mark everything as internal. This of course won't guard against reflection.

One thing that hasnt been mentioned is to ilmerge your assemblies into your main .exe/.dll/whatever, this will up the barrier for entry a bit (people won't be able to see your assemby sitting on its own asking to be referenced), but wont stop the reflection route..

UPDATE: Also, IIRC, ilmerge has a feature where it can automaticaly internalise the merged assemblies, which would mean you don't need to use InternalsVisibleTo at all



回答8:

I'm not sure if this is an available avenue for you, but perhaps you can host the assembly using WCF or ASP.NET web services and use some sort of authentication scheme (LDAP, public/rpivate key pairs, etc.) to ensure only allowed clients connect. This would keep your assembly physically out of anyone else's hands and you can control who connects to it. Just a thought.



回答9:

You might be able to set this in the Code Access Security policies on the assembly.



回答10:

You can use obfuscation.

That will turn:

int MySecretPrimeDetectionAlgorithm(int lastPrimeNumber);

Into something unreadable like:

int Asdfasdfasdfasdfasdfasdfasdf(int qwerqwerqwerqwerqwerqwer);

Others will still be able to use your assembly, but it will be difficult to make any sensible.



回答11:

It sounds like you are looking for a protection or obfuscation tool. While there isn't a silver bullet, the protection tool I recommend is smartassembly. Some alternatives are Salamander Obfuscator, dotfuscator, and Xenocode.

Unfortunately, if you give your bytes to someone to be read... if they have enough time and effort, they can find way to load and call your code. To preemptively answer a comment I see you ask frequently: Salamander will prevent your code from being loaded directly into the Reflector tool, but I've had better (ie: more reliable) experiences with smartassembly.

Hope this helps. :)



回答12:

If the assembly was a web service for example, you could ensure the designated executable passes a secret value in the SOAP message.



回答13:

Just require a pass code to be sent in using a function call and if it hasn't been authorized then nothing works, like .setAuthorizeCode('123456') then in every single place that can be used have it check if authorizeCode != 123456 then throw error or just exit out... It doesn't sound like a good answer for re-usability but that is exactly the point.

The only time it could be used is by you and when you hard code the authorize code into the program.

Just a thought, could be what you are looking for or could inspire you to something better.