views:

77

answers:

4

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

A: 

If possible try to adapt your app to web-based authentication or web-based SaaS.

Padmarag
+2  A: 

Modern processors don't have a serial number. Pentium IIIs used to but there were privacy concerns and most people disabled the feature in the BIOS. Newer Intel processors don't even have this feature. Further, since your program is in Java, you may not even be running on Intel CPU.

The sort answer is that to create a finger print for a given machine, you need to employ heuristics. Adobe & Microsoft both do this with their activation systems.

Before you go down this path, consider this. It is worth annoying your paying customers with activation, when no matter what you do a hacker will always be able to break it.

richb
+2  A: 

Flaws? Okay. I'll mention the ones I see.

  1. Pulling the JAR out of the EXE file is trivial, and after that, messing with regular ol' Java classes to get around your scheme is simple.

or

  1. Only you know the URL, eh? It would take me 2 minutes or less to figure that URL out. Network traffic is not hidden, if that's what you think. Then I'd look at your list to see what format its in.
  2. You plan involves sending the license key in a hidden field, making it easy to get a hold of.
  3. Knowing the URL, the list's format and the license key, I could spoof your domain to point to a server of mine or even my local computer, run a web server there with an identical URL to yours, and put my license key on that list. Your program would think that I'm a valid user, and off we go.

Of course, doing this I wouldn't even need a valid key, I could just spoof one in your license file, and then put that same spoofed license in my spoofed validation list.

Alex
This is the most constructive answer I've seen so far. Here are my questions :<1> You said "doing this I wouldn't even need a valid key...", that's not right, because when the app checks for key on the fly, it computes your PC's unique Id for instance "CPU_01-02-ABC" to get an encrypted result Id such as "XeR5TY67rgf" which is unique to your PC, if you copy someone else's ID, it will fail the test.<2> Yes you can get the url and find the hidden license key from the html form, but how do you put that license key into my encrypted list ?<3> Most lethal, how do you pull a JAR out of EXE file ?
Frank
It wasn't clear that your app would compute the unique ID and compare it with the one in the "Pass file" each time it ran. I assumed it would only do this computation if it didn't find an ID in the "Pass" file. And which test would it fail? Remember, I've overridden your server with my own, and on my server, my key is a valid one.
Alex
I wouldn't put it into your list. As I said, I would redirect the call to my server instead, where I have a fake list with my key in it. I can do this because messing with the network is really quite simple. The simplest way, which would probably be sufficient in this case, would be to edit the HOSTS file.
Alex
How to get the JAR out of the EXE depends entirely on how the JAR is put into the EXE, but it's usually just a matter of extracting the EXEs resources, which naturally is the place resources are put. One of these resources will probably contain the JAR file. The second option is to look for the ZIP header within the EXE file, then through a little clever hex editing, extract it. After all, a JAR file is nothing but a renamed ZIP file.
Alex
The reason I question your use of a "Pass file" in my first comment is that if you're going to do the checking against your server every time anyway, why do you need the "Pass file" at all? And if you don't do the checking against your server every time, what prevents me from just sticking the key in there myself taken from your hidden field? I mean really, what exactly is the "Pass file"'s function here?
Alex
If the Pass file doesn't exist, it just keeps running in Demo mode, if it exists but with empty license #, check my server to see if it's been added, if added that means he paid, the License # will be saved into the Pass file so next time it can find it locally without a need to connect my server. So for a paid user each time he starts his paid app, my server doesn't have to waste time, only the ones who has filled the form with user info will have a pass file, and it's very likely they have paid, so next time he starts it needs to find out if I've got payment and added license #s to my list.
Frank
Let's use an example : a user's Id is "Tom_CPU123", it gets encrypted into "secret_1", and gets passed in a hidden field html input field to Paypal, then emailed to me, I then encrypt "secret_1" into "secret_2" and put "secret_2" on my list, then "secret_2" along with few hundreds of other "secret_xyz" gets encrypted info "A_Encrypted_List", this "A_Encrypted_List" gets put on my server, which looks like this "dejjedhehw123bbsdj3j23jh..."
Frank
Every time the user starts my app it uses "Tom_CPU123" to get "secret_2", see if it exists on local Pass file, if no match or doesn't exist, goto my url and get the list, decrypt it, and see if "secret_2" is on the list, if so, save it to Pass file and run in purchased mode, otherwise run in demo mode.
Frank
So, even if you use your server to replace mine, how are you going to add "secret_2" to the decrypted list and then re-encrypt it ? Also, the Pass file itself is encrypted and looks like this : "23k4jrj34k4jf\Z\\...", how are you going to add "secret_2"[how do you get "secret_2" in the first place ?] to the pass file ?
Frank
I heard exe files are hard to reverse engineer, have you actually opened one and extracted a meaningful jar file out of it ? If so can you backup your words ? I mean, if I send you an exe file, can you show me my jar file inside ?
Frank
Concerning the exe file: I might. Again, it depends on how its put in there. The exe file format is not hard to reverse engineer. In fact, its format is open, there's no need to reverse engineer it. What's hard to reverse engineer is the machine code in it, but that's not the case here. Your application is not machine code, it's a Java Archive, most likely put into the exe file as a resource, which can be extracted easily. Just Google "exe resource" and see how many utilities that do this for you.
Alex
Well, you didn't specify that the server list would be encrypted and that there would be two secrets, one "secret_1" sent to you and another "secret_2" that is the actual license. That does change the game a bit, of course, and I'd probably opt for the JAR hacking rather than the spoofing.
Alex
Thanks Alex, that's what I thought too, I did a google on "exe resource", lots of links came up, but are there any good ones that's <1> FREE and <2> without adware/spyware, any recommendations ?
Frank
+1  A: 

Alex beat me to what I was about to say.

The existence of the license-file alone is insufficient. Your validator must also check to see whether the license-file, and the CPU-Id/Network-card Id are consistent.

Everyone
Frank