?
Solved

Creating software that runs a limited amount of time

Posted on 2003-03-05
47
Medium Priority
?
451 Views
Last Modified: 2012-05-04
I am in the need to have a version of my software that will only run for a limited amount of time, let's say 20 days.

I am quite unsure how to accomplish this in a safe matter.

I've been trying to find information on the Internet but was not very successful so far.

How do I go about this?

I guess I could just write a value to the registry or some hidden file when the software starts, and repeaditly check this value against the system time.

I'm not too worried about the system being changed as this software will run on servers, very unlikely that people are going to mess with that.

However I am worried that people will modify the information I keep that records the original start of the software, be it a hidden file, registry, ...

I want to make sure that people are unable to extend the period in a easy fashion, I would also like to make it as difficult as possible (reasonable though) for crackers to crack it.

I'm willing to raise the points for great answers.

Thank you !!!
0
Comment
Question by:FlorianJaeger
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 14
  • 13
  • 7
  • +5
47 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 8072750
>>I guess I could just write a value to the registry

That would be the way to go. Just don't make it too obvious.

Even easier - just create a key in the registry and check it' last write time using 'RegQueryInfoKey()'
0
 

Author Comment

by:FlorianJaeger
ID: 8072828
... and then somebody uses a registry monitor (from sysinternals) to find out about that key and just changes / recreates the key manually every 20 days.

I'm not sure if that's what I want ... ?
0
 
LVL 2

Expert Comment

by:keenez
ID: 8072992
I'm guessing that you want to dynamically set the 20 days (eg. 20 days from when the software is installed, not when you give them the software).

You're obviously going to have to store some information somewhere if you do it this way.  

I would suggest encoding information.  A simple implementation may be to store the expiry date in the registry and an encrypted key.  The "password" to decrypting the key may be the expiry date and hence if they change the expiry date, the encrypted key can not be decrypted properly and your program detects this and knows something was messed with.  

Unfortunately, this is vulnerable to "changing times" on the server before if you're reasonably sure somebody wouldn't do that on a server, it may be sufficient.

Also, the complexity of your encryption comes into play but there is software out there to help you encrypt some keys.

Cheers,

Keenez
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 2

Expert Comment

by:keenez
ID: 8073004
Oh ....  BTW

I would try to hide the registry key to so that you can detect if they're trying to just re-install the software to get another 20 days.

Cheers,

Keenez
0
 
LVL 86

Expert Comment

by:jkr
ID: 8073017
>>and then somebody uses a registry monitor

That is something you cannot avoid. Neither with the registry nor with files.
0
 
LVL 86

Expert Comment

by:jkr
ID: 8073076
>>I would try to hide the registry key

Good point - see http://www.sysinternals.com/ntw2k/info/tips.shtml#RegistryHidden

"Hidden Registry Keys?
A subtle but significant difference between the Win32 API and the Native API (see Inside the Native API for more information on this largely undocumented interface) is the way that names are described. In the Win32 API strings are interpreted as NULL-terminated ANSI (8-bit) or wide character (16-bit) strings. In the Native API names are counted Unicode (16-bit) strings. While this distinction is usually not important, it leaves open an interesting situation: there is a class of names that can be referenced using the Native API, but that cannot be described using the Win32 API.

How is this possible? The answer is that a name which is a counted Unicode string can explicitly include NULL characters (0) as part of the name. For example, "Key\0". To include the NULL at the end the length of the Unicode string is specified as 4. There is absolutely no way to specify this name using the Win32 API since if "Key\0" is passed as a name, the API will determine that the name is "Key" (3 characters in length) because the "\0" indicates the end of the name.

When a key (or any other object with a name such as a named Event, Semaphore or Mutex) is created with such a name any applications using the Win32 API will be unable to open the name, even though they might seem to see it. The program below, RegHide(source code is included), illustrates this point. It creates a key called "HKEY_LOCAL_MACHINE\Software\Sysinternals\Can't touch me!\0" using the Native API, and inside this key it creates a value. Then the program pauses to give you an opportunity to see if you can view the value using any Registry editor you have handy (Regedit, Regedt32 or a third-party Registry editor). Because Regedit and Regedt32 (and likely an third party Registry editor) use the Win32 API, they will see the key listed as a child of Sysinternals, but when you try to open the key you'll get an error. This is because the Registry editor will try to open "Can't touch me!" without the trailing NULL (which is interpreted as the end of the string) and won't find this name. After you've verified this exit the program and this special key will be deleted."

http://www.sysinternals.com/files/reghide.zip
0
 

Author Comment

by:FlorianJaeger
ID: 8073260
Ok, looks like I won't get around some encryption here. No problem (I hope) since I need that for something else anyway.

I am little bit worried about the user deleting that registry key, maybe I'll try that hidden key stuff with the Native API.

Maybe I'll also write the information to a file (or file stream since my app only runs on NT systems anyway) in addition, so if one of the two gets deleted it will still work. Puuhh, lot of work.

Thanks so far!
0
 
LVL 12

Expert Comment

by:Salte
ID: 8073290
I believe what you want is something like this:

store the data and possibly other info in a registry key or file or whatever.

However, you also store a special value in there. This special value is such that when you run a certain algorithm on the data the result is a known value.

THen when you read the data you compute that value if it is different from the known value you know the data has been messed with and so you can complain and stop the program or whatever. If the known value comes up you know the data hasn't been modified and can be trusted. Then you just check if the day today is after the day it is supposed to expire then you let your program exit with a perhaps some notification that they should buy the real thing which doesn't have an expiration date.

Another way is to encrypt the data you store in the key and store the encrypted data. You decrypt the data, if they have been modified you will get only garbage back when decrypting but if they are not messed with you get the proper data back and again the data are trusted.

Both ways do the same thing, you can even combine them but that wouldn't be necessary.

If you want to put some extra data the data you store can be in clear text and readable but people cannot modify the data, it is read-only for all purposes. If they modify you will notice that fact.

So how do compute that extra data? There are many ways, CRC-32 is a very useful manner. In this method you allocate a 32 bit integer for the extra data and you first set that value to 0. Next you use your CRC-32 algorithm and it will compute the extra data. You store that into the extra data element. If you now run CRC-32 again you will get the value 0 as result - if you get any value different from 0 it means that some of the data (either the original data or the extra data or both) has been modified.

Store the data and the computed CRC-32 when storing the key.

When you start the program you read the key and run the CRC-32 algorithm (the same algorithm that computed the extra data) and if the value is non-zero the data has been tampered with.

You probably shouldn't make it so obvious as calling that field CRC-32. Also if people guess that it is CRC-32 you can do any 1-1 transformation of that value after computing the CRC-32 value and store it, as long as you do the reverse operation when you load it you still get the CRC-32 value back.

Also, CRC-32 isn't really a unique algorithm, CRC-32 is an algorithm which uses a polynomial in computing it's CRC value. Obviously the CRC-32 value you compute depend very much upon exactly which polynomial you use and even though there are only a few polynomials that can be used (you can't use ANY polynomial) there are still many enough to pick from that the algorithm isn't determined. Further, the algorithm vary depending on how you consider the bits, some CRC algorithms consider most significant bit of a byte to be the first bit and others consider the least significant bit to be the first etc etc, so there are many variants of the "CRC-32" algorithm. The point is that even if people know it is CRC-32 they still don't know WHICH CRC-32 algorithm it is. Of course, they can try many different until they find one that compute the same value as you have but if you did what I suggested in doing a 1-1 function on the CRC-32 value before you store it in the registry they still won't be able to find the right algorithm.

A very simple 1-1 function to use would be to just pick some constant value C and add it to the CRC-32 value. When you then read it from the registry you just subtract the same constant value C before you compute the CRC value. Should be a piece of cake. It doesn't have to e more complicated than that, people see that the value stored which they may suspect is related to a CRC-32 value doesn't match any CRC-32 algorithm they throw at it.

Alf
0
 
LVL 6

Expert Comment

by:gj62
ID: 8073793
Unfortunately, all of the above are open to relatively easy hacker attacks, in that if the hacker can find the file or registry entry (both pretty easy to do since your program must access them at startup), they can simply delete them and be on their merry way.

Having worked for many years at a software company that used key encryption to protect their software, here's what I can tell you:

1) NOTHING is foolproof, not even what I recommend here <grin>
2) By far, the most secure method is hardware key encryption - these systems are now quite good, and you have to REALLY want to break the system to defeat the hardware key.  That said, if you don't access the hardware key periodically throughout your program, a hacker can just hack out your call to the key and replace it with an expected response.  So, you still have work left to do.
3) You can not use a hardware key, but a demand/response system.  This is going to be similar to the above, except that it requires the user to call you (or go to your website) and give a key string that is generated based upon the current date/time/machine that they are trying to install on.  They are given a response string back that will ONLY work for that key.  Since the key can't easily be regenerated, you have some protection that they won't simply hack the file.  You can then store the license file (encrypted) in plain sight.  This will work if you aren't concerned about the downtime if they have to reinstall the software for valid reasons (such as their system crashed).  Again, even if you do this, you have to make "hide" your access to the file throughout your software, or a hacker can just modify your code to "fake" the expected return from the file.

Bottom line, all the rest of these answers represent a pretty good 80/20 rule - you are going to prevent 80% of the hackers with 20% of your effort.  To signficantly improve upon that, and knowing you will never get to 100%, you are going to have some real work ahead of you.

Lastly, the software we had sold for $50,000 up to $1,000,000, so it was worth our efforts to protect it.  If you are protecting a $500 piece of software, definitely stick to the 80/20 rule...
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8074655
Here's a useful addendum to the above described techniques:

Once you are certain that the user has exceeded the demo period or has deleted the registry key, then most software just puts up a message box saying "please buy blah blah blah..."  But here is a more createive solution:  Start to introduce subtle bugs into your output.  For instance, rather than outputing a report, output a bunch a greek letters that just look like a report!  But this one will drive them crazy! -- make the screen go all blue and display a cryptic message about system error.  The really cool thing I found about that technique is that its pretty easy to do; I found out about it entirley by accident!  In fact, just accessing the special dongle device driver a certain way will take care of it for you.

-- Dan
0
 
LVL 12

Expert Comment

by:Salte
ID: 8078217
Actually, if the program require the key to be present at startup and refuse to run without the key he can't just remove the key. Also, using some form of encryption or CRC will prevent the key from being alterered.

If user deletes the key he/she must then contact the vendor (you) and ask for a new key, i.e. it's like they must purchase the program again.

Nobody will just delete the key under those circumstances.

Alf
0
 

Author Comment

by:FlorianJaeger
ID: 8080200
Thanks for all the responses - I'll have to digest the information now.

Also please note that I NEVER said that I would need the protective measures to sell software, I was talking about a trial version.

Here is a summary of what I think I will do.

In order for the trial version to only run a limited amount of time I will encrypt some information with the expiration date as the key. I will also save this information in a file hidden somewhere.

In addition I will not create this file / key immediately upon startup but X minutes after the program was started, preferrably random. This way you can't just monitor the registry/file activity after the program started up.

My biggest concern is to prevent someone from simply deleting the file/reg key (and then my app would think the trial version is just starting and create the key).

And by the way, the software sells for as low as ~$150 per installation so I don't want to spend too much time on it.

Another thing that I am thinking about right now is having some kind of serial number that knows about the expiration date. So I could give the user who is evaluating a serial number that has the expiration date encrypted in it - this way he absolutely needs an serial number and the serial number only works for a limited amount of time.

But the implementation seems difficult. How does the application know the serial is correct? If I hardcode the serials into the app then couldn't somebody just look at the source and figure it out?

Thoughts on that would be really helpful ...

Thanks.
0
 
LVL 6

Expert Comment

by:gj62
ID: 8080485
How about the "serial number" just being an encrypted version of the date, plus a simple checksum or CRC of the string?  Yes, someone could decompile it and figure out (a) your key, (b) what the string really is (c) the encryption algorithm, if they recognized that is was TEA, and (d) the checksum you used, but that would be alot of work for $150 software!

You can use TEA - http://vader.brad.ac.uk/tea/tea.shtml - complete with source code - it's small and fast.  There are a plethora of sites for checksum or CRC source code, just use google...

0
 
LVL 12

Expert Comment

by:Salte
ID: 8080615
I think that you should rather just create the key with expiration date when you install the program. This way, when the program start it can expect the key to be there and won't by mistake create the key if the user deleted it. The program NEVER creates the key, the installation program does that. The program just expect the key to be there.

Also, just putting the date in the key is probably not a good thing, that way smart people can copy the key from one machine to another.

Generate a new key for each person who purchase the program, the key is such that it has a self-check, i.e. you can run an algorithm on the key and it will return a bool value if the key is valid or not. This way the program itself doesn't have to know about or care about the contents of the key per se but can just run that algorithm and validate the key. Once the key is validated you can extract from it two pieces of info: 1) the expiration date and 2) info about the computer.

If the expiration date is gone then the program should display a polite message that it is overdue and you should buy the software or whatever or get a new version. If the machine is incorrect then the user has just copied the file from another machine.

Now, this machine info is somewhat tough one, if you're on network you could use IP number but if people use DHCP that won't work - however, the ethernet card's MAC address can be used if people are expected to have such a card. This address is unique for every ethernet card and is a 48 bit number.

If no network you can try to get other semi-permanent info from the computer. Be aware that if the user replaces hardware or upgrades he might have to get a new key from you then.

If the program is a network program you can probably get some info from the network hardware. Ethernet cards has that 48 bit MAC address, dialup cards typically have a telephone number, the user isn't likely to change telephone numbers very often and if he does you can always have him contact you and get a new key.

You generate the key and ship it with the program. The program doesn't have the key anywhere, it does have the algorithm to validate the key.

The validation is done by adding extra digits of letters at some position in the key so that a certain algorithm always give a known result. This way the key can change and the program will still run ok as long as the new key is also valid. Of course, if people find out about the algorithm to validate the key the scheme is broken.

As someone already said, some hardware thing is a very good protection and is used by certain expensive software. However, it isn't good for any software for several reasons:

1. If all software were to use such a thingie, the computer would have a zillion of them plugged in. These things are usually placed in a printer port or some such place (USB port perhaps) and works in the way that when you send a specific code to that specific port, you get a specific result back, If you send anything else, the thing will forward it to the printer or whatever. The specific sequence you send to it is a sequence that is not needed by a printer or if needed by a printer it can be quoted in some way, so that the thing will send the string to the printer instead of responding in its special way.

You place your driver in between the regular printer port driver (or whatever port) and the port and then intercept whatever it send and make sure your special sequence is never sent or if sent that it is quoted. Then when your program want to test if the user has this thing the program open a connection to the driver and tell it to send it special sequence and then return the response back. If you got what you expected then the user has the thing and can run the program, otherwise he doesn't have it and he can't run.

However, if you have several such things they all have to place themselves between the regular printer driver and the printer port, this means that the system will be clogged up by various interceptors for every block of data sent to/from the printer.

2. You need to write your own driver for that hardware stuff, if it is just a little demo program it's not worth the effort. Such hardware things are only used by really expensive programs where the vendor is very cautious about illegal copies. The vast majority of software do not use such hardware protection for the obvious reasons once you know what is going on.

All in all, I suggest you use a key which is made up of three parts:

1. The expiration date and possibly time.
2. Some info about the machine/user/PC whoever is given the permission to run the program so that he cannot just copy the key file from some other user.
3. Some additional data which is used as an advanced parity check. For example a very simple (don't use this) example is: the value is encoded as a string of digits, so the date is 8 digits YYYYMMDD and then 6 digits of user info and then 1 digit so that the sum of all the digits is equal to exactly 7 when you ignore multiples of 10:

20030306123456
if you add the digits together you get:

2 + 3 + 3 + 6 + 1 + 2 + 3 + 4 + 5 + 6 = 35
ignoring multiples of 10 we get 5, we needed a value of 7 so we add an extra digit of 2, so the key is:

200303061234562

This is a very simple example and I will suggest you use a bit less obvious algorithm but the principle is clear, a program can now test if this key is valid or not without having a table of legal keys or anything and the user will have to know the exact algorithm if he is to produce a valid key. This prevent the case that the user just copies the key from some other place and using that extra information allows the program to validate a key without having the key hardcoded into the program.

Alf
0
 
LVL 6

Expert Comment

by:gj62
ID: 8080763
Alf,

The generation of unique information per *computer* for the trial software of a $150 program is going to be very costly.  If I understand you correctly, the trial user will have to call to get the key once a unique piece of hardware is identified.  That's asking quite a bit out of your customer...

I agree that your approach will definitely increase security, but you've just added $10 of sales cost to an already low-priced piece of software...

I recommended the hardware key prior to knowing exactly what he was trying to protect.  They also come with preconfigured drivers that will work for most apps.  I agree however that it would not make sense in this context...
0
 
LVL 12

Expert Comment

by:Salte
ID: 8080989
gj62,

It depends on what info he uses. If his software is network software then he can probably expect some tcp IP settings, he can even use IP number in a DHCP setting provided he mask away the particular bits that may vary. It wouldn't take much effort to get the IP number of your own host.

If the user has an ethernet card then he can use the MAC address or part of it. Again, not very costly.

If it is not network based he could do something simple and just get the username of the user and run some algorithm on it, provided the other user who 'steal' that keyfile has a different username and/or password you will detect it. If the user somehow guessed that this was what you used and specifically created the same username as another person just to use your low priced software then I guess it is fair enough, the chance that he can do that is rather small...

My point is that you can virtually pick anything you want as long as it is assumed to be semi-permanent info about the user or the user's machine and the information is likely to be different on anyone else's machine.

If it is a low cost software then you probably can provide some automated way for a user to get a new key if he lost his old etc, it's enough that you get a logfile and can run a program and check if someone inform your automated web site that he "lost" his key file every 30 days or so...

You don't have to block him from getting a new key but seeing that he did get a new key a few times can then just let you put him in a special file where he is barred from getting a new key next time or he gets a key that will somehow cause him troubles, for example that it expires after 1 day or 20 minutes or whatever. If he still want the hassle of getting a key from you every day you can start to block him from getting a key at all etc...

The point is that most people will not go to such length just to run the program free if it is low cost. They will rather just pay the money and get over with it.

Alf
0
 
LVL 6

Expert Comment

by:gj62
ID: 8081048
Alf,

It doesn't matter what info they use.

My point was that interacting with a user costs money - every support call, every sales call, etc.

If the user is not very knowledgeable, walking them through the necessary steps to get the info you request will take even more time/money.

Granted, you could do an automated web-site service, but you'd have to pick something that every user has.  Earlier I think he said it was designed to run on servers, but still, getting that piece of information - correctly - is going to cause them alot of support headaches even with an automated system.
0
 

Author Comment

by:FlorianJaeger
ID: 8081167
I think I like gj62 suggestion the best, I would really rather not have the user to contact me for every machine he wants to evaluate the program on. I wouldn't mind having the user install the trial on 5 servers to see how it works.

Instead & ideally I would send him a serial number. The service would have to verify the serial number and extract / decrypt the expiration date out of it. I would set the expiration date on a per / customer basis.

Customer 1 calls me on March 5th and says hey I would like to evaluate, I send him a serial and the trial version that will run until March 31st for example.

I would also need to make sure that even if some cracker finds out how to create those serial numbers that the service has a maximum time. In the example just mentioned I would hardcode an expiration of 4th of May. Then it would just stop. I would keep adjusting this maximum to the current date - a maximum always around 2 months from the current date.

I would make this function that checks the maximum date inline and put it into several places in the code to make sure the cracker can't take it out.

If the user wants another trial he has to contact me personally, there is no place to download it. So even if he cracks the serial algorithm he can't just keep downloading new version every 3 months or so - he has to contact me.

All this is based on the assumption that a company evaluates my product and either buys it or not.

How does this sound like?

I would have a version that runs for a limited time, even if the algorithm is cracked it will soon stop and I would only have to create one serial number. Also the user wouldn't have to worry about contacting me for every server.

Now I just have to figure out how to safely create this serial number ...
0
 
LVL 6

Expert Comment

by:gj62
ID: 8081334
Because a hacker can always disassemble your code, you can't really make the serial number "crack proof".  There are a variety of encryption algorithms you can use, including public key encryption, that would allow better-than-average security, but then again, you could just use TEA, as I said before (it's advantage is it is trivial to implement).  

That keeps the key encrypted, so nobody would know what was in it just by looking at it - they'd have to crack into your code.

What you put in the key, beyond the expiration (or the start) date, is up to you.  Since just the date would not yield a very long string, you can put something else in it, but that just makes it longer, not really more secure.  

You talk about hardcoding an expiration - that means a separate compile of your main software every day - are you sure you want to do that?  Besides, that's the easiest of all to defeat - once you find where the date is stored, you just watch to see when that memory is accessed - whether you check once or a million times, it really is no more work for the hacker to defeat it that for you to create it...

Lastly, unless someone is doing this just for fun, I doubt many serious hackers are going to expend too much energy to circumvent $150.  Unless you are worried about rampant piracy overseas, I wouldn't work too hard on this...

Have you thought about a trial version where certain features are disabled that don't really affect the operation, but would make the product unusable in a production environment?  Just a thought...

Good luck - hope you are successful
0
 

Author Comment

by:FlorianJaeger
ID: 8081390
Well I'll have do a separate compile anyhow since the real version currently does not require any serial numbers, it just works. I'm not too worried about pirating once the customer bought it.

So you don't recommend to hard code an expiration date? I just thought that I could annoy crackers with that.

I already have a FREE "light" version that has a subset of the features - but customers want to have the REAL version to see if all the disabled features really work. Unfortunately ... more work for me.

I think that I'll just TEA - I'm surprised to see how short the source code is ... make you wonder.

I will also have to use public key encryption at some point but all the sample files I've seen look AWFULLY complicated ... puuuh.
0
 

Author Comment

by:FlorianJaeger
ID: 8081448
Well I'll have do a separate compile anyhow since the real version currently does not require any serial numbers, it just works. I'm not too worried about pirating once the customer bought it.

So you don't recommend to hard code an expiration date? I just thought that I could annoy crackers with that.

I already have a FREE "light" version that has a subset of the features - but customers want to have the REAL version to see if all the disabled features really work. Unfortunately ... more work for me.

I think that I'll just TEA - I'm surprised to see how short the source code is ... make you wonder.

I will also have to use public key encryption at some point but all the sample files I've seen look AWFULLY complicated ... puuuh.
0
 
LVL 6

Expert Comment

by:gj62
ID: 8081451
Yes, TEA offers good encryption if you don't have either  the encrypting/decrypting algorithms - it is not complex so a person with the decrypting algorithm and the key can back into the encrypting algorithm without much problem.

That said, it is the 80/20 rule - 80% of the benefit for 20% of the effort - anything else will cause you alot of effort.

Yes, the hardcoded date does annoy the crackers, but you have to compile *each time* you want to change the hardcoded date - with just the "date-key" trial version, you only have to compile it once...
0
 
LVL 6

Expert Comment

by:gj62
ID: 8081569
A minor change to the above...

My understanding (I am not skilled in ciphers) is that TEA offers very good encryption if you don't have the key.

Having the encryption/decryption algorithms, or even the source code, really won't help you if you don't have the key itself.

However, if you have the key AND either the decryption or encryption algorithms, it is not too difficult to back into the other algorithm.
0
 

Author Comment

by:FlorianJaeger
ID: 8084405
I think I am getting pretty close now but I'm not sure if I am going to use the TEA algorithm simply because it's a symmetric algorithm.

With a symmetric algorithm I will have to include the key in the app that the user gets.

I will instead use a public key algorithm (I am looking at RSA right now), this way I will include the public key in the app that is shipped to the user and I will keep the private key.

This way it will be almost impossible for the user to create a fake serial number since he would have to obtain the private key.

I'm looking at the Crypto++ Library right now (http://www.eskimo.com/~weidai/cryptlib.html) and while extremely complicated (in my opinion) for people not using crypto stuff that often and I don't even use C++ features that often I have to admit) it does compile as a library which should make the whole thing doable, I will see.

So will send the user the expiration date encrypted with the private key. The app will then decrypt it with the public key.

Sounds like a pretty good solution - comments?
0
 
LVL 6

Expert Comment

by:gj62
ID: 8084454
True - but as you said, it is a bit more code <grin>...

Remember, however, that at some point your app will translate your key into clear text (or something similar that you can test with) and hence the encryption is ONLY really going to protect someone from modifying the key file that you send, and not hacking the program and simply circumventing the test of the date altogether.

In other words, if someone has taken the time to (a) discover your key (b) reverse engineer your encryption (c) build their own encryptor and (d) understands what's in the file so they can recreate it, they can circumvent the date check after your public key algorithm just as easy...

This is EXACTLY what I meant when I said we were working with an 80/20 rule...

However, there shouldn't be anything wrong with your approach, except that it is more work and you aren't gaining more security...
0
 

Author Comment

by:FlorianJaeger
ID: 8084698
If I use a symmetric algorithm and they disover the key that is embedded in the application and know the encryption algorithm I use then they can simply generate their own serial numbers with ease.

If I use public key algorithm then they can only discover the public key and have to modify that public key that is embedded in the binary in order to create their own serial numbers. Something I consider more complex and time consuming for the cracker.

Would you agree with those statements?

I also didn't think that adding a public key algorithm is very complex, something I might be wrong about.

I also would like to use a public key algorithm in another project so it would be worth researching that ... frankly I already posted a question in the "C" forum :-)))
0
 
LVL 6

Accepted Solution

by:
gj62 earned 1000 total points
ID: 8084752
Go for it - here were the points I was trying to make:

1) The public key algorithms and code are more complex.  Adding it to your project shouldn't be more complex if you've got a decent library and you understand the API.

2) If I were trying to crack your program, I wouldn't bother with your key at all - I would find where you test your key after you decrypt it, and see what value you are expecting from the *test*.  I not interested in the key -just hacking around it - completely disabling the need for a key!  Unless a hacker is doing a homework project, they aren't going to bother with your keys...

3) Once hacked in the manner of #2, you've got a completely "open" program - it will never stop running due to an invalid key - that's why I'd hack it that way.

4) It matters not what type of encryption algorithm you use, since the approach is not to hack the key (there is nothing in the key of importance), but to hack the program to run forever...

Not, of course, that I ever hack commercial software...
0
 

Author Comment

by:FlorianJaeger
ID: 8085487
Allright,

I think I know what you are getting at. A cracker wouldn't give a XXX about the keys, they would just try to circumvent / disable the part in my code that checks for the time.

So essentially it doesn't matter all that much what code I use. Aha, makes sense.

Well, I'd say it doesn't hurt if I can get the RSA stuff to work since, as I said, I need it for something else anyway. It wouldn't be lost time then.

I don't even want to guard against professional crackers, they wouldn't be interested in that app anyway (and if they do then I feel flattered). I just want to guard against the occasional skilled admin who has too much time (I used to be one of those :0 ).

Both solutions (tea, rsa) should provide adequate protection I would say.

Wouldn't you :)
0
 
LVL 6

Expert Comment

by:gj62
ID: 8085516
Yep - good luck!
0
 
LVL 12

Expert Comment

by:Salte
ID: 8086805
Well, there are ways to prevent the scenario of gj62 also.

You start up your program and the very first thing you check is

1. The integrity of your own code, just do a CRC check or something like that on the binary code of your program. Make sure to skip relocatable data items (items the linker fix up), information about where they are, are found in the .EXE file.

2. If your exe file hasn't been tampered with, you check if the user is running some other program that might intercept, debug or otherwise tamper with your program. Also, note that the integrity check in 1 will also catch any attempt at setting a breakpoint anywhere since debuggers set breakpoints by replacing parts of an instruction with a breakpoint instruction. When handling the breakpoint the code will typically restore the old byte at that location and so the program can continue - after the debugger has done its thing.

Of course, you can also trace where the breakpoint handling goes. You should probably also check the debug registers and other places where there are traces of the trace instruction.

Note that none of this will work properly if you run in a virtual machine. You can't even trust the VM flag to be honest since the virtual machine can give you a fake status register where the VM bit isn't set even if it is.

The only way to be sure you're not running in a virtual machine is to avoid connecting to any DLLs that might put you in a virtual machine and take over. Probably a sanity check on your DLLs.

All in all rather costly, but some of these things are being used in commercial software.

Wouldn't be worth it to put it in low price software though so I essentialy agree with gj62. However, I doubt many people would work hard at cracking a program that is low priced to start with. Crackers will typically try to do those things for expensive software, professional software used in businesses etc. So I don't think you should worry too much about those crackers, just make a key, probably encrypted, it doesn't have to be advanced, just enough that the user doesn't recognize that "here is the date" and so that the users can't simply just copy the key files from one machine to another.

It isn't completely crack proof but I am sure it would be enough for your program and it can be done relatively easy.

Alf
0
 

Author Comment

by:FlorianJaeger
ID: 8087877
Thanks Alf,

It probably is a little too complicated but definitely something to think about so I appreciate your comments (and the comments from earlier).

For example I wouldn't know how to do the checksum while skipping parts ... but someday maybe !
0
 
LVL 12

Expert Comment

by:Salte
ID: 8088429
Easy enough to skip them, you just don't include them in the algorithm. To find which places to skip you must read the .EXE file and know the format of it and how to decode it. This also makes it very platform specific.

Not something you would do for a small simple program but something you can have in mind if you one day make a big program that you would try to protect as much as possible.

One very good way of protecting your code - if you make a very expensive program one day is this:

Don't give the customer the code, he get an identification and a small uploading program. Using this program he will identify himself and if he is allowed you give him the code. He doesn't store the code on disk in the usual way but rather just let it stay in memory and call functions in it. The uploading program locate functions in the code and places it in a place where you can run it. Then the vital parts of your code is never stored in a file on his hard disk and the code should be very well protected.

This require the user to be on net when running your program but in many situations for an expensive program for professional business use that might not be an unreasonable requirement.

He can't hack the code when he never has it. Of course, some cracker might look into that uploading program and try to fake it, so that they can grab the code, but there are ways to protect that too. using techniques discussed earlier.

You don't really have to make it completely crack proof. It's enough that you are able to discover when someone attempts to crack it once. Then you know who they are and you can guard yourself against them. Very few crackers are able to make something that bypasses all blocks on the first try and if you can manage to send a message to your homeserver when you discover such an attempt you can block them from further attempts.

Alf
0
 

Expert Comment

by:SpideyMod
ID: 8107000
A request has been made to split the points on this question at:
http://www.experts-exchange.com/Community_Support/Q_20545522.html

gj62 - 250 points - he solved question
salte - 150 points - he helped a lot with his comments


I am reducing the original question points down to 250 so you can select gj62's answer and award the points there.

I need you to create a new question titled "points for salte re 20539468".  Give that question 150 points.  Then grab the URL for the new question, return here and let salte know where the question is.  Make sure to create the question in the experts-exchange.com/Programming/Programming_Languages/Cplusplus/ area so the points go in the right place.

If you need help or if the "points for" question is not created within a couple of days, somebody let me know and I will handle it.  Thanks.


SpideyMod
Community Support Moderator @Experts Exchange
0
 

Author Comment

by:FlorianJaeger
ID: 8107860
Wow, that couldn't be any more complicated :-)
0
 

Author Comment

by:FlorianJaeger
ID: 8107864
Thanks, that's what I'm going to do.
0
 

Expert Comment

by:SpideyMod
ID: 8107916
Imagine when we have to do this for abandoned questions.  I do about 20 splits a day during cleanup.

The good news is that a simple split mechanism is supposed to be included in the rewrite to be released soon (don't ask when because I truly do not know).
0
 

Author Comment

by:FlorianJaeger
ID: 8111565
How do I let Salte know?
0
 

Expert Comment

by:SpideyMod
ID: 8112061
You post back the link to the "points for Salte" question in this original question so email notification will happen.  I've taken the liberty of finding the question you posted and putting it here:

Salte, points for you at:
http://www.experts-exchange.com/Programming/Programming_Languages/Cplusplus/Q_20546338.html

SpideyMod
Community Support Moderator @Experts Exchange
0
 

Expert Comment

by:robin_at_mri
ID: 8517590
Hey all,
Read this post and wanted to say thanks for the information!  I followed the link to the TEA implementation but it was broken.  Does anyone have an updated link I could use?

Thanks.


Rob
0
 

Author Comment

by:FlorianJaeger
ID: 8517702
That should be the official link to the University of Bradford, I'd wait a day and see if the server is up again - otherwise I'd search on google for mirrors or the source code (which is very small)
0
 
LVL 6

Expert Comment

by:gj62
ID: 8517846
0
 

Expert Comment

by:robin_at_mri
ID: 8518025
Thanks,
I have the implementation of those methods already.  Just was hoping to come across the complete implementation of the TEA encryption in C++.  That way I do not have to recreate all of the methods that initialize the key and data arrays  (k[0] - k[3]. and v[0] and v[1] respectively).  


R.
0
 
LVL 6

Expert Comment

by:gj62
ID: 8518170
Not as a separate entity.  You could probably search through crypto++ and extract it, but by the time you do, the small amount of code you'd have to write to make this happen on your own would be easier than sifting through this lib... but it is interesting nonetheless...

http://www.eskimo.com/~weidai/cryptlib.html

0
 

Expert Comment

by:robin_at_mri
ID: 8519133
Would anyone have the complete code?  My C/C++ is shaky at best and need to finish this off asap.


R.
0
 
LVL 6

Expert Comment

by:gj62
ID: 8519691
Here's the sample code in C - you can easily adjust it for your own purposes (not my code, came from a TEA page...  BTW, printing the encoded string generally doesn't work because it can encrypt NULLs into the string, so be sure you treat the result as an array and not a string...

void encipher(unsigned long *const v,unsigned long *const w,
  const unsigned long *const k)
{
  register unsigned long       y=v[0],z=v[1],sum=0,delta=0x9E3779B9,
                   a=k[0],b=k[1],c=k[2],d=k[3],n=32;

  while(n-->0)
     {
     sum += delta;
     y += (z << 4)+a ^ z+sum ^ (z >> 5)+b;
     z += (y << 4)+c ^ y+sum ^ (y >> 5)+d;
     }

  w[0]=y; w[1]=z;
}

void decipher(unsigned long *const v,unsigned long *const w,
  const unsigned long *const k)
{
  register unsigned long       y=v[0],z=v[1],sum=0xC6EF3720,
                   delta=0x9E3779B9,a=k[0],b=k[1],
                   c=k[2],d=k[3],n=32;

  /* sum = delta<<5, in general sum = delta * n */

  while(n-->0)
     {
     z -= (y << 4)+c ^ y+sum ^ (y >> 5)+d;
     y -= (z << 4)+a ^ z+sum ^ (z >> 5)+b;
     sum -= delta;
     }
 
  w[0]=y; w[1]=z;
}

/*

int main()
{
   char acKey [ 16] = "123456789123456" ; // place your key here
   acKey[15] = '\0';
   char acTestInput[] = "How would i use these functions to encrypt/decrypt a char* ?";
   char* pInBuf;
   char* pOutBuf;
   unsigned long ul8ByteAlignedSize, ulInputSize;

   ulInputSize = strlen ( acTestInput);
   ul8ByteAlignedSize = ulInputSize + ( 8 - ( ulInputSize % 8));

   pInBuf = ( char*) malloc ( ul8ByteAlignedSize);
   pOutBuf = ( char*) malloc ( ul8ByteAlignedSize);

   memset ( pInBuf, 0, ul8ByteAlignedSize);
   memset ( pOutBuf, 0, ul8ByteAlignedSize);
   strcpy ( pInBuf, acTestInput);

   for ( unsigned int i = 0; i < ul8ByteAlignedSize; i+=8)
   {
      encipher ( (unsigned long*) ( pInBuf + i), (unsigned long*) ( pOutBuf + i), (unsigned long*) acKey);  
   }
   printf("%s\n",pInBuf);
   memset ( pInBuf, 0, ul8ByteAlignedSize);

   for ( i = 0; i < ul8ByteAlignedSize; i+=8)
   {
      decipher ( (unsigned long*) ( pOutBuf + i), (unsigned long*) ( pInBuf + i), (unsigned long*) acKey);  
   }
   printf("%s\n",pInBuf);

   return 0;
}
0
 
LVL 12

Expert Comment

by:Salte
ID: 8523127
Encrypted data should always be treated as binary data anyway - i.e. if you want to print it, print each byte in hex or some such, don't treat it as text.

Alf
0
 

Expert Comment

by:robin_at_mri
ID: 8523745
Thanks guys!  I appreciate the help.


R.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

801 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question