I have intellectual-property coded into .net 2.0 fully-trusted assemblies (.exe + DLLs) on an end-user machine, which I would like to protect from being hacked / reverse-engineered (WebService / Cloud-Computing solutions are not an option). Below is a list of techniques I gathered in order to reach this goal.
My questions are:
- Are my assumptions correct, or am I doing something wrong in one or more of the techniques?
- Will this list be sufficient in order to prevent a malicious attack, or are there other protections I should add?
Thanks in advance.
--
Suggested Techniques
- Sign all assemblies with the same strong-name key.
This has two benefits:- A. Make sure any modification to an assembly will render it useless,
- B. All assemblies will have the same public key, by which they can identify each other.
- Digitally sign the assemblies: Both let the users know that the executed code came from the correct source, and – add another identification component by which assemblies could identify each other.
- Enforce the above by crawling up the call-stack and verifying that all callers are inside the “community”.
Possible leads:- Hallgrim’s idea in this S.O. thread.
- Daniel Brückner‘s addition in this S.O. thread.
- This .Net Security Blog Post, which combines both solutions.
- Use AOP (e.g. Spring.NET) to inject the call-stack crawling code into some/all methods.
- This is mainly done because there’s no single entry point (like DllMain() for Win32 DLLs) in a .net assembly.
- Obfuscate all assemblies in order to hamper reverse-engineering and reflection-execution attempts (strong name signing will be performed after obfuscation, of course).
- Integrate a System.ComponentModel.LicenseProvider mechanism.
- Make use of the “InternalsVisibleTo” assembly-level attribute in order to expose internals among a pre-defined set of assemblies.
- Possibly use NGEN in order to convert the solution to native code.
Points to Consider
- Implementing part or all of the above will most-likely introduce a performance penalty, so time-critical processing, for example, should be handled with care.
- CAS seems to be irrelevant for this type of fully-trusted assemblies.