As discussed in similar questions here and here I want to protect my code from reverse engineering.
My situation is as Simucal describes in his (excellent) answer h
one option is to use the license key and/or hardware fingerprint to decrypt the sensitive code at runtime and emit it as IL; this will make it invisible to static reverse-engineering tools (e.g. Reflector)
also detect the presence of a debugger and refuse to run in debug mode, except possibly in very limited circumstances (i.e. on your machine)
note that this will make debugging very difficult for you, and nearly impossible for others (if this is an end-user app that's not a problem, but if it is a library or framework for other developers to build upon, that's a problem)
note also that making a copy of physical memory to disk and using offline tools on the memory-dump will reveal your decrypted algorithm, so it is fairly easy to defeat - but far more trouble than most people will bother with
the whole thing is a trade-off between difficulty for you vs deterrence for the few bad apples vs potential loss due to theft/plagarism
good luck, and let us know what you decide!
You should obfuscate the complete code since it gets harder to reach that small valuable part. The smaller the code gets, the easier it becomes to understand it. Most obfuscators should not mess with public interfaces since there are many obfuscated libraries out there.
However I think you should rather convince users that there are no special tricks there instead of trying to hide it. To quote Kaiser Soze, "the greatest trick The Devil has ever pulled is to convince the world that he doesn't exist".
And of course you can always file a patent for your invention and protect yourself legally.
Most obfuscators allow you to specify which methods/classes you want to keep from being obfuscated. SmartAssembly for instance let you mark methods or classses with attributes, while others let you select the methods in a UI to exclude from the process. You ought to be able to have pretty fine grained control of the process, and so you can have your cake and eat it.
You will however run into problems if you are using reflection.
If your code is that sensitive, put it where nobody can get to it.
E.G. provide a client or web page for people to access some service that exposes your functionality.
That service can sit behind an external firewall and communicate with a backend server behind an internal firewall, where your sensitive code runs.
For extra measure, obfuscate that code.
This would require compromising several layers of security before getting to your code.
You can obfuscate it at the C# or CIL level but what is really going to make it impossible is that the IL compiler is designed to create the most efficient machine code that it can to actually execute.
So, to reverse engineer your algorithm, get the machine code and run standard disassembly tools on it. Trace the data through the system by following it forward from the standard input API calls to the standard output API calls.
Face it, if someone wants it, they can have it.
You can make it hard to casually figure it out. For example, I wanted to see what was in some database managed by a Java application. It turned out that the Java decompile was really messy, full of odd functions and classes and namespaces all with the same names, intentionally trying to hide what was really going on.
I could have fixed up the decompiler I was using so that it renamed everything as A_namespace instead of just A and then the function flow would have popped right out to the Eclipse call tracing graphs.
Instead I just threw up my hands and got on with real work rather than rewriting decompilers.
So, you can hide it from casually interested folks, sure.
I've heard good comments about the Spices.Net Obfuscator. It should be able to greatly increase the time necessary to get at the algorithm.