I know software companies use licenses to protect their softwares, but I also know there are keygen programs to bypass them. I'm a Java developer, if I put my program online for sale, what's a reliable and practical way to protect it ?
How about something like this, would it work ?
<1> I use ProGuard to protect the source code.
<2> Sign the executable Jar file.
<3> Since my Java program only need to work on PC [I need to use JDIC in it], I wrap the final executable Jar into an .exe file which makes it harder to decompile.
<4> When a user first downloads and runs my app, it checks for a Pass file on his PC.
<5> If the Pass file doesn't exist, run the app in demo mode, exits in 5 minutes.
<6> When demo exits a panel opens with a "Buy Now" button. This demo mode repeats forever unless step <7> happens.
<7> If user clicks the "Buy Now" button, he fills out a detailed form [name, phone, email ...], presses a "Verify Info" button to save the form to a Pass file, leaving license Key # field empty in this newly generated Pass file.
<8> Pressing "Verify Info" button will take him to a html form pre-filled with his info to verify what he is buying, also hidden in the form's input filed is a license Key number. He can now press a "Pay Now" button to goto Paypal to finish the process.
<9> The hidden license Key # will be passed to Paypal as product Id info and emailed to me.
<10> After I got the payment and Paypal email, I'll add the license Key # to a valid license Key list, and put it on my site, only I know the url. The list is updated hourly.
<11> Few hours later when the user runs the app again, it can find the Pass file on his PC, but the license Key # value is empty, so it goes to the valid list url to see if its license Key # is on the list, if so, write the license Key # into the Pass file, and the next time it starts again, it will find the valid license Key # and start in purchased mode without exiting in 5 minutes.
<12> If it can't find its license Key # on the list from my url, run in demo mode.
<13> In order to prevent a user from copying and using another paid user's valid Pass file, the license Key # is unique to each PC [I'm trying to find how], so a valid Pass file only works on one PC. Only after a user has paid will Paypal email me the valid license Key # with his payment.
<14> The Id checking goes like this : Use the CPU ID : "CPU_01-02-ABC" for example, encrypt it to the result ID : "XeR5TY67rgf", and compare it to the list on my url, if "XeR5TY67rgf" is not on my valid user list, run in demo mode. If it exists write "XeR5TY67rgf" into the Pass File license field.
In order to get a unique license Key, can I use his PC's CPU Id ? Or something unique and useful [ relatively less likely to change ]. If so let's say this CPU ID is "CPU_01-02-ABC", I can encrypt it to something like "XeR5TY67rgf", and pass it to Paypal as product Id in the hidden html form field, then I'll get it from Paypal's email notification, and add it to the valid license Key # list on the url.
So, even if a hacker knows it uses CPU Id, he can't write it into the Pass file field, because only encrypted Ids are valid Ids. And only my program knows how to generate the encrypted Ids. And even if another hacker knows the encrypted Id is hidden in the html form input field, as long as it's not on my url list, it's still invalid.
And of course this Pass file itself is encrypted, not in clear text.
I can't have any process running on the web server hosting the url with valid list, it's run by an ISP that doesn't support Java, and I don't want to write another server side program in other languages to add into my process, so the most I can do is ftp over the latest valid license list.
Can anyone find any flaw in the above system ? Is it practical ? And most importantly how do I get hold of this unique ID that can represent a user's PC ?
Edit :
Form the first few answers, I heard things like : "No matter what you do, it can be broken". Thanks, I suspected that, that's why I posted this, it's just too general, can someone be more specific ? Like, I can do this and that to bypass your step <8> or <12> ? I'd like to hear concretely what can be done to break it, so I can fix my approach.
Frank