Obfuscation is one way, but it can\'t protect from breaking the piracy protection security of the application. How do I make sure that the application is not tampered with,
How to make sure that the application is not tampered with, and how to make sure that the registration mechanism can't be reverse engineered.
Both have the same very simple answer: don't hand out object code to untrusted parties, such as (apparently) your customers. Whether it's feasible to host the application on your machines only depends on what it does.
If it isn't a web application, maybe you can allow for SSH login with X forwarding to an application server (or Remote Desktop Connection, I guess, for Windows).
If you give object code to nerdy type persons, and they think your program might be fun to crack, it will get cracked. No way around it.
If you don't believe me, point out a high-profile application that hasn't been cracked and pirated.
If you go with the hardware keys, it'll make production more expensive and your users are going to hate you for it. It's a real bitch to crawl around on the floor plugging and unplugging your 27 different USB thingies because software makers don't trust you (I imagine).
There are packages out there that will encrypt your EXE and decrypt it when the user is allowed to use it
Of course, the way around it is to crack the "can-I-use-it" test so that it always returns true.
A nasty trick might be to use the byte values of the opcodes that perform the test somewhere else in the program in a dirty way that'll make the program crash with high probability unless the value is just right. It makes you linked to a particular architecture, though :-(