Everything You Need To Know About Registration Systems

… but were afraid to ask.

One of the most common questions asked on the Business of Software board by a new aspiring uISV is “How do I protect my software?” This post is meant to be a comprehensive answer to that question, so folks can point to it and say “Alright, now get out of my hair!”. Kidding, kidding, we were all there once.

First, a brief discussion on why you want to protect your software. The only reason you want to protect your software is to enforce the limitations you have put on the trial version. Many people mistakenly come to the table with the assumption that protecting the software will somehow, magically, “protect my intellectual property” or something to that effect. This might be theoretically true but you will have an easier time conceptualizing your registration scheme if you think of it as primarily a marketing, rather than technical, measure. Its your salesman that encourages folks to pay you money.

Why is it important to remember your registration scheme is a salesman? Because salesmen do not typically kick their prospective customers where the sun doesn’t shine, and many registration schemes do. Aside from some clubs in Tokyo (and the less you know about them, the better, really), people generally don’t pay money for the privilege of being kicked. Yet many software developers keep including Nutcracker Suite protection systems, such as Starforce, which severely harm the user experience, out of the mistaken belief that this will eventually increase profits.

If you will permit be a bit of amateur psychoanalysis, I think this is because software developers in general, and uISVs in particular, feel violated when someone is using their software illegally. I know the feeling, it has happened to me (and, mark my words, it will happen to you). Someone who downloads your software and cracks it hasn’t cost you any more money than someone who picks your door and walks around your apartment for 20 minutes without touching anything, yet the feeling that your rights have been violated is the same. And perhaps in a fit of less-than-rational anger you might demand your apartment upgrade its security system to include dead-locks, pitbulls, a batallion of US Marines with shoot-to-kill-orders, and some cleverly disguised booby-traps involving acid or flaming oil, or perhaps just flaming acid. Of course, the local Girl Scout troop selling cookies will probably not react too well to the fortifications (aside from the “cute wittle puppy!”), so if you like having cookies delivered to your door this is probably not a good idea.

So lets talk about four classes of users and how they interact with your registration scheme.

The first type of user is perfectly honest and will always comply with your licensing scheme to the letter, even if ways to circumvent your registration scheme are obvious. Approximately everyone thinks they are this kind of user. To this kind of user, your registration scheme (a salesman for your software) can be only a hindrance in getting to use the software which he happily paid for.

The second type of user is mostly honest. He’s not a pirate, after all, he has a wife and kids and works at an insurance company. He scoffs at the kids on Napster who feel entitled to free music. And yet he also will happily buy one license of your software when your license tells him he really requires five, install and uninstall a time-limited trial version every two weeks, and perhaps even reset his system clock to get around a time limitation. But he won’t download a crack, no. A crack would be stealing, and stealing is wrong. This second type of user is where your protection (a salesman for your software!) will make most of his keep. How many of these users relative to totally honest users you have depends on your market, but sadly, they’re a lot more common than most non-developers would think.

The third type of user wants to use your software, but will pirate it given half the chance. Its too expensive, it doesn’t do quite what he needs, he doesn’t have the money, for-profit software development is evil, piracy is wrong but oh well… he has a lot of mental excuses. Some of this user group is very technically adept at finding cracks — they know what IRC channels to go to and what shady connections to excercize. Some of them rely on Google searches. You can potentially wheedle a small number of sales from this group with your protection scheme, and they’ll hate you for every minute of it.

The fourth type of user… “Do what you want ’cause a pirate is free, YOU ARE A PIRATE!” He flies the Jolly Roger and you will never, ever make a legitimate sale to him. Even if he does “buy” your software it will be with a stolen creditcard or chargebacked within 24 hours. You’ll find that there are countries on earth (*cough* China *cough*) where there are few users from any other type. Your protection system is not really relevant to this type of user, since he’ll be using the crack anyway.

Oh, yeah, lets talk about cracks a little bit. You. Will. Be. Cracked. I really strongly recommend you read that post, because its true: no protection scheme will survive indefinite contact with the adversary. Your goal in instituting a protection scheme is not to achieve 0 utilization of your software by the Jolly Rogers of the world. It is primarily to keep circumvention methods obscure enough that it will take dedicated effort to discover either a way around your software or find someone who has found a way around your software.

There are several varities of cracks which you have to worry about. We are now crossing into the technical portion of this article, and will be discussing implementation details rather than philosophy, so pay attention.

1) A single good key. The cracker discovers, either via a “legitimate” purchase or analyzing your code, one single good key, and publishes it. This is the least damaging type of crack, because you can just ban that key in further updates to your software, and because if you use keys which are tied to other user data it will prevent someone from using the good key without otherwise impersonating the user it is tied to.

2) Keygen, or “key generators”. You have one of these lying around on your PC or server which generates good keys for your software. The cracker’s goal is not to replicate your system, but instead write one which produces at least some subset of the keys your system will produce. Many crackers prefer to write keygens because they get a psychological thrill out of “beating” you, but to most user groups there is no difference between one download and another.

3) A patch/crack which strips off your protection. For example, if you leave in a debug mode (if (!debug) {checkRegistrationKey();} else {registered = true;}), all the patch has to do is modify your executable to flip the debug bit and then your software is locked into the registered version. Creating a patch requires that your executable be a stable binary, as if the offsets of the bits to flip change applying an old patch will be impossible.

4) A cracked executable. This is the cracker’s least favorite method, because then he has to spend non-trivial amounts of bandwidth hosting the executable, and since he wants to host literally tens of thousands of executables this is irksome to him. However, remember, bandwidth is cheap — this is a speed bump, not a security mechanism.

In general, it is to your advantage to force the adversary to use countermeasures which are higher up that list. This means that your protection scheme should:

1) Require user-specific data so that a single good registration key does not break your software everywhere. The most obvious choice is username, but this is not very secure. Other popular choices include hard drive serial numbers, MAC addresses, GUIDs, etc. Remember, this will inconvinience legitimate users — you will have users who spell their name differently on their Paypal accounts versus in your software (example: McKenzie != Mckenzie has gotten my mother a few times, Bob Smith versus Robert Smith), you will have users who expect (and are perhaps, depending on your license, entitled) to use the software both at work and at home, you will have users whose hard drive dies and your software will cease to work on the new one. All of these become support issues for you, because your salesman is busy trodding on the toes of people who have already given you money. Consider carefully how much pain you will authorize him to inflict. For myself, I thought the risk of a serial key leaking was less than the amount of difficulty I would have policing unique serials, so while I ask folks for their name to generate my keys they’ll actually work for any name you put in (Shh, don’t tell the crackers :) ).

2) Obfuscate your code. Especially if you are using an interpreted language, such as .NET or Java, decompilers exist which will print out your protection routines in their entirety. This was how my very first hacked in version 1.0 happened, and that resulted in a keygen (i.e. total tactical victory for the bad guys). I’ve since started using ProGuard, a lovely OSS utility which takes your nice, easily decompileable JAR file and returns gibberish which still executes. This plus a (partial, backwards compatible) fix for the earlier keygen has kept me from getting hit with another wave of me hearties from China, although I know of at least one functioning keygen out there — but its buried beyond the reach of my casual pirate customers, which is a total strategic victory for me. Obfuscation is nice in that unless you need reflection or debugging stack traces it can’t hurt a legitimate user.

3) Change binaries early and often . Frequently changing your binary, via any method you want (obfuscation utilities can often do this — so can minor patches to your code), forces pirates to either host the executable themselves or deal with “customer support” requests like “Waaaaaah your patch doesn’t work anymore lol”.

OK, now, finally, on to license key generation algorithms. Some design considerations:

1) Are you going to run this offline, or are you going to run this on a server?

2) How much information from your customer does the algorithm require? How are you going to get this? e.g. if you require their hard drive serial number, you suddenly add the requirement “Customers can only purchase my application through my application”, which may be less than desireable.
3) Are you going to roll your own, or use an off-the-shelf system like Armadillo? In general, you’re not paying for security (although its likely that their system is more secure than yours, its not totally secure), you’re paying for convinience. Armadillo has been broken before and will be broken again, like every other security system.

4) How do you get the registration key to the user? Do you want to display it on a website, display it on an email, or update the application directly (sometimes called “automatic key injection”? A lot of the payment processors (including e-Sellerate, as I recall) promote systems that have this as a feature. Its quite nice, as it reduces customer support headaches (what was my registration key? How do I input it again?), particularly with non-technical customers. I didn’t do this myself, primarily because it required more development effort than my schedule had time for.

OK, if you’re still with me, lets talk some strategies for key generation if you want to do it yourself.

1) Public key encryption. Basically, your registration key sends a message: “Bob Smith, I hereby give you the right to use my software, in exchange for the consideration you have given me”. The problem is that Jolly Roger wants to be able to forge the message and replace Bob Smith with Jolly Roger, thus bamboozling your program into functioning for him. Luckily, there is a solution to this: public key cryptography. Public key cryptography works like this: you have a pair of keys. One of them is public and you can give it out to everybody, including the adversary. One of them is private and you guard it with your life. Since your trial version will be in the hands of the adversary, the only thing the trial version can know is your public key.

Practically speaking, you first take the hash value of all the identifying information you have. Then, you encrypt this with your private key: the output of this encryption is your “registration key/serial number”. Your software then performs the same calculation of the hash value in parallel, and decrypts your serial number using your public key, which results in a hash value. If the two hash values match, you unlock the software. If not, you display a nicely worded message to contact support (remember, your protection mechanism is a salesman).

If you are interested in the math behind encryption, which gets kind of heady, Wikipedia has a nice article on RSA. I’ll give you my dirty little secret: I’ve got a very incomplete understanding of a lot of the number theory involved, and I don’t trust myself to implement encryption. Neither should you. Really, trust Bob Schneider, you’ll probably just end up breaking something. Instead, take the crypto library which comes with your package of choice, and USE IT. Look for “MD5 digest” or “message signing” in your documentation if you’re unfamiliar with the whole field and just want to be done, quickly.

2) Everything else. Any other mechanism is insecurity which you’re tolerating for the sake of preserving your time as a developer. With that in mind, for preventing casual piracy you don’t need to go as far as public key crypto, although I would oh-so-strongly suggest doing so. I ignored my own advice though, and did something similar to the following: take two random constants A and B, which are “secret” in the sense that you have to actually decompile my program to find them (“But Patrick, thats not very secret is it. After all, the program is in the hands of the adversary.” EXACTLY). if (serial ^ A) % B == 0, then the serial is good. Note this doesn’t allow for any use of identifying information, and was chosen totally because I could implement it in 30 seconds. If I did another product today, I would spend 30 minutes instead and use Java’s excellent crypto libraries. The weaknesses of my approach are obvious: with access to the code breaking it takes a matter of seconds, one serial number will work for any number of computers, etc etc. But it was sufficient to my purposes because my target customer has enough difficulty getting a legitimate version installed, to say nothing of navigating the dark corners of the Internet where the keygens flourish.

Where/when to check the serial number: I check once on startup. A lot of people say “Check in all sorts of places”, to make it harder for someone to crack by stripping out the check. If you want to be particularly nasty to the cracker, check in all sorts of places using inlined code (i.e. DON’T externalize it all into SerialNumberVerifier.class) and if at all possible make it multi-threaded and hard to recognize when it fails, too. But this just makes it harder to make the crack, not impossible, and remember your goal is generally not to defeat the cracker. Defeating the cracker does not make you an appreciable amount of money. You just need to defeat the casual user in most instances, and the casual user does not have access to a debugger nor know how to use one.

Alright, that about wraps it up. This article is a work in progress, so I might beef it up some more, perhaps with code samples or techniques to impose, e.g., time limitations. Someday. In the meanwhile, I hope you learned something.

[Edit: Yo ho, me hearties.  If ye be wantin’ to stick it to a pirate without having to program a thing, cast yer glass over this way.]

No Responses to “Everything You Need To Know About Registration Systems”

  1. Ali September 5, 2006 at 11:36 am #

    I came up with two additional techniques:
    - A new serial code can be randomly generated whenever a purchase is made and an IPN is sent to a script on the server by paypal etc. When this happens, you email this code to the user and store its copy in the database. Then, the application can send a HTTP POST to http://www.yoursite.com/checkcode.php and provide the serial code given by the user, and have it validated from the website.

    - You can just create a hosted web app instead of a program which they install on their own computers and never have your program cracked. (OK, Ok, sometimes it won’t work but thats still a nice option).

  2. Patrick September 5, 2006 at 1:42 pm #

    Ali: if you’re going to phone home, you should be phoning home with their user information and accepting the serial number as the output of your server’s script, not phoning home with the serial number and accepting a boolean, etc, as the output. i.e. you should be doing key injection, not key verification. Key verification has to ultimately happen within the application, which is why public key crypto is the best way to do it. The reason is that the Internet connection is also in the hands of the adversary :) You’re a hosts file change away from a break-once, break-everywhere exploit if your software is just expecting to read a boolean off the Internet.

  3. Jericho, the JoS anti-piracy crusader September 5, 2006 at 2:32 pm #

    This article is simply fantastic.

    I have a few things to add:

    Ali, the technique you mention is called online activation. I have used it with great success. However, you must carefully implement it so you leave as few vulnerabilities open as possible.

    Regarding the 4 types of users: I have tried to explain on JoS this concept for years, without success. The concept I tried to explain is what I call the “crack spread”. It doesn’t matter that a crack (or keygen, or pirated serial, or whatever) exists for your application. What matters is how many people have access to the crack. If most type II users have access to the crack, the sales will drop.

    If an user can type in Google “YourAppName serial” and find a working pirated serial, then your income from the software will drop.

    If the serial is just on 2 or 3 obscure pirated software sites, this doesn’t decrease your sales because the crack is available only to type IV and some type III users.

    However, once a crack exists, if your app is popular, the crack WILL spread, and in a few months, it will become easily available to type II users, so your income will drop.

    What can you do about this? Release a newer version of the app, harden your protection, blacklist pirated keys, make sure the crack doesn’t work (by simply decompiling the software), etc, etc.

    In my opinion when buying ASProtect or Armadillo you are really buying security AND convenience. Your app will still get cracked, but it will take longer to get cracked. These programs also make it impossible to create a keygen for your app, because they use public key cryptography.

    Make your own protection ONLY IF you know encryption very well AND you know assembly language AND you cracked some software yourself. Then, you have the chance to make a strong protection.

    If this is not the case, just buy ASProtect or Armadillo. When you have the time, add your own checks – check if the app is still packed, CRC check your .EXE, etc.

    Other advice.. do not taunt or provoke the crackers. They are very proud individuals with a lot of time in their hands, and if you taunt them, they will spend a lot more time to prove how clever they are.

    Do not make an “interesting” or “challenging” protection. Many crackers crack for the intellectual challenge alone. Make your protection hard to crack but as boring as possible.

    To find cracks, watch your web site’s web server logs. Many crack sites will link directly to your downloadable files, so you will know (from the REFERERs) about the cracks quite quickly. For this, you need a good web server logs analysis program, I’m sorry but just Google Analytics won’t do, because the crackers often link directly to your setup file, and Google Analytics doesn’t “sense” that – only a web server logs analyser can.

    Search Google Groups for your app, and you’ll often find pirated serials which you can blacklist.

    One final sad news for us, software developers: unfortunately bandwidth it very cheap nowadays. There are several sites which will host any uploaded file, even if it’s hundreads of MB large, and allow unlimited downloads. Many of these sites will ask the downloaders to pay to download, but still allow the download if the users don’t pay (but there is a time delay of a few minutes, etc).

    I won’t say which sites they are, but they are well known in the pirated software communities.

    There are also private forums with tens of thousands of users each.

    So.. you shouldn’t rely on the fact that the crackers can’t host a cracked version of your software. In fact, this is very easy.

  4. Jericho, the JoS anti-piracy crusader September 5, 2006 at 2:36 pm #

    Instead of “by simply decompiling the software” I meant “by simply changing the software a little and recompiling it”.

    This defeats most cracks which look for specific offsets.

    There are some cracks which search for byte patterns in search for the place to patch. They usually aren’t defeated by a recompile, but if your .EXE is packed (by ASProtect, Armadillo, etc) these kind of cracks must first unpack the .EXE.. and if you use a good packer such as ASProtect, the cracker will be able to unpack the EXE manually using an assembly level debugger such as SoftICE, but won’t be able to create a tool which unpacks the .EXE automatically (to apply the byte patches afterwards).

  5. Impressionable September 6, 2006 at 3:17 am #

    Patrick,
    Thank you for such a good resource on this subject. As I get closer to rolling out my first product (late fall), I will refer to this repeatedly, I’m sure. In the last several months (as I have started following BoS), I have really come to appreciate your posts, and my respect for you (starting at the “I don’t know this guy” level) continues to increase rapidly ! Please continue posting on the topics us greenhorns don’t yet know. Actually, do the work that makes your living FIRST, and then help us impressionable novices !

    Thanks again !

  6. Vignesh Swaminathan September 6, 2006 at 10:02 am #

    Patrick,

    Thank you for publishing this article based on my request. This is a example of topics which is very much needed by new microisvs but for which there is no basic data available in public domain. All of us spend time the hard way and learn them, atleast you are one among us who are ready to help others by documenting your experience and not brushing it of as kiddo topics.

    The article wonderfully covers the basics and points to some good resources for achieving s/w protection. My side of the coin is that how does one get this done for an ASP based application like mine? (i am currently searching for obsfucators for ASP)

    I guess a combination of keygen & obsfucation/compilation of ASP code would do the trick but it would be good to have some confirmation.

    Thanks again

  7. Vignesh Swaminathan September 6, 2006 at 10:13 am #

    Patrick,

    Thanks for your article. This is an example of a topic which is much needed by microisvs but does not have much basic content available in the public domain. Everyone has learnt these the hard way and you are one among us who is willing to help others by documenting your experience. Cheers to you for that!

    The article covers the basics of the concepts and points to some good resources which i will end up using. My side of the coin is that how does this work for an ASP based application like mine.

    Based on your article, i am thinking of a combination of keygen and obusfucation or compilation or encoding (windows script encoder). Am i right in thinking in this direction?

    Thanks again,
    Vignesh

  8. Patrick September 6, 2006 at 11:14 am #

    For folks like Vignesh who get caught in the spam trap, I apologize in advance. I get roughly 20 spams per every legitimate comment so turning off the filter isn’t an option. If you don’t see your comment pop up immediately, don’t worry, it will be back after I get back to the blog (likely after I wake up, since most of you post while I’m asleep) and check the questionable spam pile for misclassified posts.

    One thing you can do to avoid getting munched on is including a real email address, or even a fake email address which looks real. @hotmail.com and other obvious free addresses, however, get heavily penalized by Kismet (the anti-spam engine).

  9. Patrick September 6, 2006 at 11:15 am #

    Ah yeah, I should mention: words like “keygen” will automagically get your comment blacklisted until I can review it. There is, unfortunately, nothing I can do about that.

  10. Patrick September 6, 2006 at 4:05 pm #

    I’m going to take the liberty of moving rhubarb’s comment here, since it was accidentally posted in an unrelated thread but is fantastic:

    >>
    The serialz and keygens are only useful because they work on the publically available trial version right. Now, your crippling of the trial version amounts to an integer somewhere (15), but a lot of crippleware products could put the extra features in separate, dynamically loaded classes.
    In other words, the real version installer can “contain” those extra features, so no keygen or cracker can make the trial version work.

    This raises two more barriers: 1. the crackers have to get a paid-for version to start cracking, 2. they have to redistribute the whole app with the crack each time and pay for the bandwidth.
    Speed bumps, as you say, but sizeable ones. No?

    But I’m guessing there are usability problems with this approach or that it doesnt work well with the payment providers like payloadz and watchamacallit-junky.
    Can you tell us if it does?
    >>

  11. Patrick September 6, 2006 at 4:10 pm #

    So Rhubarb, as to why I don’t do it that way: I don’t want to require a download after the purchase, because this throws up a barrier between me and my customer’s money. You’d be downright shocked about the number of teachers who buy my product at school and then put it on a floppy disk to take home with them. Floppy disks! Amazing. Anyhow, the utility of me making sure Gladys from Springfield* can use Bingo Card Creator the way she wants is more than the utility I get from from frustrating 10,000 Jolly Rogers.

    * Not an actual customer name, but has the feel of an actual customer name :)

    Incidentally, for folks who are curious, payloadz and e-junkie will support that use case very well… I just don’t want to inflict it on any elementary school teachers.

  12. Patrick September 6, 2006 at 4:55 pm #

    Oh, I just released a new security patch for my software and turned the evil bar up just a wee bit. Rather than just blacklisting the most popular pirate key, I:

    1) Have the program crash unaccountably
    2) … the first time you try to verify the serial number (I verify around all protected operations, incidentally) after some random time interval X. X is chosen to give a random hacker *just* enough time to verify “Yep, that serial unlocks the registered version” and forget that he’s just registered it, then *boom*. Not enough time to get anything seriously accomplished.
    3) … the crash is caused by a daemon thread, which is an anonymous inner class (anonymous inner classes are God’s gift to paranoid folks — running one popular Java decompiler on my security class causes the decompiler to spout total gibberish — it identifies the daemon thread of doom as a utility thread that I cooked up for my printer control class, which just amuses the heck out of me )
    4) … but there’s not just one daemon thread, there’s a pool of the suckers (of a totally random size, naturally). And they all look alike, and are all waking at random intervals to perform some suspicious looking calculations, but you have to actually step through the calculations to see which thread is the poison pill. (Side note: effect on end-user experience is zero, or I would have done NONE of this. I waste about 1ms of CPU time per minute.)

    Of course, this doesn’t quite beat a pirate who has a key generator… but I suspect it will cause a little angst in China tonight. And it took, oh, 5 minutes to do and another 20 to test (would hate to have a legitimate customer crash to desktop, now wouldn’t I?)

  13. Brian September 7, 2006 at 6:29 am #

    Patrick, you wrote: “I know of at least one functioning keygen out there — but its buried beyond the reach of my casual pirate customers, which is a total strategic victory for me.”

    Just wondering: how in the HECK do you get information like that? Where would I look for information like that about my utility, Ducklet DeskPhoto, which is also a v1 launched at the same time as yours?

    Also a followup on your last comment about random crashes: in one product I worked on, a co-worker implemented the random crashes idea and took it a step further: before the random crash, he corrupted the stack with a bunch of caca-poopoo. But we were using C++…that technique is harder to use in a language like Java or C#.

    And finally, Chris Thornton of ClipMate has described a really useful technique that I think he invented called Partial Key Verification. Quick summary: he only validates *some* digits of the key, which makes crackers think they’ve cracked the code when they’ve really only cracked part of it. In the next update of his program he removes the check for some digits and adds checks for other digits. Next version, same thing again. The only way a cracker can create a key or keygen that will work in the next version is if he’s clairvoyant. Which most people aren’t.

  14. Patrick September 7, 2006 at 7:11 am #

    >>
    Just wondering: how in the HECK do you get information like that?
    >>

    Referrer logs help a lot. After I find a yohomehearties.com has a link to me, I do some quick checking of the obvious searches in Google to see if I can find them. If I can, I see whether they require any sort of authentication to get the Bingo Card Creator patch. If I can’t find them in 3 minutes on Google or they require any sort of signup process to get the patch, I judge their threat to me as approaching zero. Incidentally, having a passable command of Chinese helps. (I pass my brother the commands! :) )

    >>
    And finally, Chris Thornton of ClipMate has described a really useful technique that I think he invented called Partial Key Verification.
    >>

    This is brilliant beyond all speaking of it, if you’re not working with public key encryption. If you are working with public key encryption, nobody is writing a keygen unless you screw up royally on the implementation. It comes with the same security built in: it is impossible, to the limit of our current understanding of mathematics, to use the information which is in the source code to produce a single functional key in a “reasonable” amount of time.

    Still, I do love the idea. It would have cleaned a lot of the dirt off of my dirty hack if I had had access to it two months ago :)

    Oh, here’s a quick-and-dirty implementation of the same basic strategy, using my dirty-hack above as a base:

    Pick A, a really large random number.
    Make a list of factors F1 through Fn. Good candidates would be 5 numbers.
    Let B = the product of F1 through Fn.

    To generate your serials, randomly make multiples of B and then XOR them with A.

    In your program, ship a constant C, which is created by multiplying together a random subset of B.

    To validate a serial, the serial is good iff (serial XOR A) % C == 0.

    You can generate a new C for every version of your program trivially, and all your generated serials will continue to work while all keygens will break and have to get recompiled. It won’t be a difficult process: they just have to hear that their previous keygen is broken, decompile your code, find the constant, change the constant in their code, and release. But this process buys you a couple of weeks every time you patch, for literally 5 seconds of effort on your part. And if you want you can have an automated build process silently update your executable every day of the week with a new C, which will force someone to host a known good executable to run a keygen against.

    But, remember, for 30 minutes more effort once you could have been using public key encryption. :)

  15. Derek Pollard September 7, 2006 at 7:47 am #

    Hi Patrick,

    Many thanks for the article, especially as I asked a registration question on BoS which you kindly responded to.

    I’ve happily worked on implementing public key encryption in my registration process. The only thing I’m puzzeled by is your ’30 minutes more effort’. I agree that in the application this is certainly the case, especially as I’m using Java like yourself ;-) However that also then requires a server side solution which performs the private key encryption with user-specific data. As far as I’m aware that rules out using solutions such as e-junkie unless I’m missing something.

    I’m currently planning to write a server side registration processor, inspired by your response on BoS to my question, so please stop me if I’m reinventing a wheel!

    Thanks again,

    Derek.

  16. Patrick September 7, 2006 at 8:28 am #

    You do need a server side script, which you can implement in your choice of programming environments. I would personally do it in Perl, because you can do it in 10 lines or less with the CGI and Crypto modules. And thats using whitespace, which I hear gives real Perl developers allergies. Then you tell e-junkie/payloadz to use the generator script, and give them the URL of the script to pass the data to (both services support this easily). If you’ve got further questions on how to accomplish this, I’ll post a how-to.

  17. Derek Pollard September 7, 2006 at 8:48 am #

    Patrick,

    I’d be very interested in any help with the integration you suggest. You’ve potentially helped bring my release date way forward. I know very little Perl, but given a simple example I can get running with any language I’ve encountered. My starting point would be enough of a script to at least discover if my hosting service, which does support Perl, also has the Crypto modules installed (if they are optional).

    Sorry if this is a silly question, but the contents of the Perl cannot be seen from the web the same as PHP? You can tell I’m more of an application than web developer.

    Cheers,

    Derek.

  18. lb September 9, 2006 at 6:10 am #

    brilliant brilliant article. thank you very much for this rundown. we’ve built our own registration more or less from scratch for TimeSnapper 2.0 (our product) and faced (or will face!!) all the problems you mention here. excellent rundown!!

  19. Robin September 17, 2006 at 3:27 am #

    We support quite a few protection software like ASProtect, VBOLock. Armadillo unfortunately does not come with a standalone KeyGen anymore .. however we are looking for a workaround.

  20. Rishabh October 23, 2006 at 5:53 pm #

    Live life

  21. Tarek Demiati May 31, 2007 at 10:01 am #

    Thank you very much Patrick,
    this is a great article which have spare me the need to reivent the wheel

    I need a few clarifications regading the few points below :

    You wrote : “Change Binaries early and often”
    * Question : What kind of changes do you perform in the binaries beside adding the newly blacklisted keys ?

    You wrote :
    “you first take the hash value of all the identifying information you have.”
    * Question : 1 – If I understand correctly you take the hash of the “user name ”
    (or other customer related details) + the public key – Is this correct ?
    2 – How do you handle the black listed key, if you regenerate
    a hash value using the same parameters
    (hash value of user name + public key)
    you will end up with the same serial number (which is then black listed in
    your binary ?)
    Do you use a date and time generation parameter for that ?

    * For a given product do you ALWAYS keep the same public key during the entire life of the product, from Version1.0 to Version 9.0 ?

  22. Patrick May 31, 2007 at 11:53 am #

    1) Adding a few keys will do it, as that should change the binary structure enough to throw off the patching code. Your mileage will vary on this. You could also do anything which would bork the byte offsets — recompiling in a different optimization level for a C-based program, etc.

    2) You’ve got it.

    Your #2) I suppose you could.

    3) That is certainly the easiest way to do it. If you don’t you will be constantly regenerating keys for customers who already bought version 2.3 of the software when 3.0 comes out, with the new key generation algorithm. If 3.0 requires an upgrade purchase from 2.3 then changing the key might be a good idea.

  23. Tarek Demiati May 31, 2007 at 8:06 pm #

    Another question :-)

    Is there any guidelines to follow for creating “a good” public key ?

    Does choosing a simple & short public key could be fatal is providing a robust protection ?

  24. Patrick May 31, 2007 at 11:53 pm #

    Your public key will be algorithmically generated from your private key. Since it is embedded in software, no one has to type it in, so it can be as complex as you need it to be. I’d suggest 256 bits or better. Your private key, which will never be given to anyone other than yourself, will be the same length. You can fairly easily generate one of these by taking a strong password and hashing it with MD5 to the appropriate length.

  25. Derek Pollard June 17, 2007 at 4:03 pm #

    Patrick,
    It has been a while, but I’m pleased to say that I have public key encryption implemented in my registration key system. Getting it running in Java was easy, then the PHP side wasn’t much harder (except that I’m a PHP novice) and once I had figured out how to share the keys it was running. What a moment that was :-) Now that is a system that I can just reuse in future versions and products.
    Cheers,

    Derek.

  26. Patrick June 17, 2007 at 4:56 pm #

    Congratulations!

  27. Jez June 18, 2007 at 4:33 pm #

    Patrick :

    How do you handle the smart user who uninstall the trial version one day before it expires and then reinstall it ?

    The Private/Public Key does not solve this problem

    On windows do you have to flag something in the registry to handle this ?

  28. Patrick July 4, 2007 at 1:15 pm #

    My first answer is “Ignore them, because they’ll win anyhow, and if they don’t win they’ll just download a cracked version of your software”. This remains my best answer. But if you really want to use your time trying to frustrate a small segment of the non-cooperative population:

    But you could save the date of install in the registry somewhere, and leave it after an uninstall. The only problem with that is folks can easily use software to see exactly what keys your app leaves in the registry, and they can rollback to a “clean” state.

    You can drop a file somewhere on their hard drive — ditto. Watch changes to the filesystem, revert them, done. Or, run the software in a virtual machine.

    You can have your application “phone home” on install with a bit of hashed data which is personally identifiable for the computer, like say the hard drive serial number, but these things can be changed at will and phone home schemes WILL annoy honest users.

  29. Tracy October 3, 2007 at 6:51 am #

    Very nice read, something I am thinking about as we are developing a piece of software. Nice to read a blog where the editor has a sense of humour

  30. Clay Dowling October 12, 2007 at 1:51 pm #

    Patrick,

    Just wanted to say that this is a very good article and covers a lot of stuff that people need to know. It should probably be listed on the BoS wiki. I wrote my own registration component using a symmetric encryption technique rather than the asymmetric method of public key encryption, which seems sufficient unto my needs. I wrote the article up here: http://www.lazarusid.com/how-lazarus-registration-works.html

  31. Justin December 3, 2007 at 8:30 pm #

    I’m not sure the public key encryption method works. You say to guard the private key with your life but in the next paragraph say that your software “decrypts the serial number” which requires use of the private key. a hacker look in the code to determine the encryption key and generate their own forged product key by encrypting it with the same key used for decryption. it seems that any symmetric encyrption algorithm could work just as well. another simpler approach is using a hash function in the code and making the product key = [unhashedportion]+[hash]. if the user types a product key where the second part is not the hash of the first part you know it is invalid. in other words, the approach described here is security by obscurity, and there are simpler methods than symmetric encryption to accomplish that.

    i think only assymetric cryptography SIGNATURES can prevent forged license codes. the license code should be digitally signed (not encrypted) by the software publisher using a private secret key. then the software embeds the public key and verifies the signature. inspecting the code won’t help hackers because they’ll only find the public key there, and that is not enough to generate a signature. in other words, the product key becomes [serialNumCapabilities]+[SignatureOfPrevious]. the problem is that an RSA 512 bit key signature is 103 base32 characters, which is cumbersome for the user to type in.

  32. joske vermeulen March 10, 2008 at 3:36 pm #

    Typo police alert: 4th paragraph: “If you will permit be ” -> “If you will permit me “.

    Anyway, Justin: you are right. What Patrick means (I think :) ) is to use a signature and to check that signature with the public key. I’m also not quite sure why you’d need to use a hash of the identifying data or the relevance of the md5 remark. As far as I can tell (and how I’ve implemented it :) ) it’s enough to make a signature of the username and any eventual other identifying information. You then check the signature with the public key which you’ve embedded in your application.

  33. malcolmm October 8, 2008 at 8:17 am #

    Great article and great links too – thanks. I’ll be revisiting it when I get to this point in the project I’m working on at the moment. I’ve already specified a license server, but I think that I may revisit it when it comes to coding it. When I’ve worked out what I’m going to do I’ll post on my blog and I’ll definitely be referencing your useful content.

    I’m particularly concerned about allowing the legitimate user to use the software from more than on location (laptop, home etc), but not allowing duplicate users on the same license – hence license server.

  34. attila October 14, 2008 at 8:20 pm #

    I have just one question. Why don’t you create a demo version instead of the trial? It could add watermark to the cards, or something similar. When somebody purchases a legal copy then he will receive the full version.

    Best regards

  35. Matt C December 3, 2008 at 5:55 pm #

    > I don’t trust myself to implement encryption. Neither should you. Really, trust Bob Schneider, you’ll probably just end up breaking something.

    Yeah, I liked the cryptography advice in “Blue Skies for Everyone”, though you kinda have to read between the lines to get it.

    Also, I heard Bruce Schneier had his own rock and roll song steganographically embedded into the text of Applied Cryptography. Who would have thunk it?

    :)

  36. TD May 21, 2009 at 2:11 pm #

    Great article. I have read and re-read some parts for several weeks now. I have thoughts/questions on this subject.

    First, it appears that it does not matter how you impliment a product key protection scheme for your app as there will always be a group of hackers who will decomplie your app to learn how the product key protection scheme works.

    Second, it appears that the next group of hackers may not go to the trouble to decompile but spent time trying to crack the scheme used to create the product key itself.

    I read where one way to keep the hackers at bay is to “patch” (whatever that means) the app so that the product key protection scheme is changed regularly in some small way. Does not doing this break the keys issued for earlier “patched versions” of the app?

    I am thinking I’ll just create an app to generate a list of product keys and issue one to the customer when they make a purchase. In the app I’ll have code that checks the key to see if it meets some scheme I’ll come up with. I know if it is decompiled that the scheme will be known but it sounds like it’s not worth worrrying about that.

    Any thoughts on my thoughs?
    TD

  37. TD May 21, 2009 at 2:15 pm #

    Need to re-word this part of my last post:

    I am thinking I’ll just create a list of product keys and issue one of these keys to the customer when they make a purchase. In the app I’m selling I’ll have code that checks the key to see if it meets some scheme I’ll come up with. I know if it is decompiled that the scheme will be known but it sounds like it’s not worth worrrying about that.

  38. Elliot Axel September 11, 2009 at 10:13 am #

    How about a piece of software that was written in1995 (still very useful to some of us), is set up on a 30 day trial requiring registration to continue using it. Author died 10 years ago, and all the registration links are long gone. I just downloaded a copy of this software, but can’t use it after Oct 10….

  39. Nash February 1, 2010 at 5:50 am #

    Hi everyone,

    Can you please explain me how the Online Activation technique works coz i need to implement it in one of my product (some basic steps as in what all inputs are requried to the registration server and what is the best way to secure this activation process) and what are the best possible ways to store the license info on machine for example registry, license file etc.

    I have integrated the manual activation for this product already.

    Thanks

  40. Matt February 12, 2010 at 6:32 am #

    I’m using less known executable protector PELock for 3 years now, it’s a little bit clumsy to use, basically You need to wrap your sensitive code parts into encryption markers:

    int DemoCode()
    {
    DEMO_START

    printf(“You will need a license key to run this code”);

    DEMO_END

    return 0;
    }

    I admit my software isnt’t as popular as I would expect it to be :P hehe, but it hasn’t been cracked yet, I guess more popular copy protections are already better analyzed and described.

  41. Michael Hubert April 11, 2010 at 3:22 pm #

    Personally my favourite methods of keeping pirates out are:

    - Server-side security.

    - Total program obfuscation.

    I primarily work with c# .NET, so bear with me.

    The first thing to note is that what pirates want is to be able to run your product as if they bought it, with as little crap bugging them as possible. So I implemented server-side security, using Windows Communication Foundation, I am using functions that are implemented on my own server. Then whatever data is generated, is returned back to me, in an SSL-secured fashion. Therefore much of the functionality of my program, comes from being able to login to my server, and use what functionality my server offers to them.
    Now this is what allows me to channel the attacks. All of my security is centered around “This user on our server does not have the permissions to do this” or “This user does not even exist”. Because of this, the attacker cannot crack my server, and therefore bypassing my security is not so simple.

    The attacker must emulate much of my server functionality in a cracked executable. He must rewrite large portions of my code, and recompile those into a new executable, or even rewriting them directly into my executable. Now this is where the obfuscation comes in. I will use Smartassembly for this example, but there are other solutions much like this. With Smartassembly, it both protects your executable and obfuscates the code. Meaning that even if someone is able to get your code into readable format, it will still be one giant jumble. A big bonus to this is that the executable will no longer run anymore, so the attacker is left to only being able to read obfuscated code.
    Well this makes it difficult for the attacker to actually crack my executable, because they can only edit it if they remove the protection, and they can only run it if the protection is still there. Even to this date, Smartassembly 2/3 have not been cracked to a point where attackers could run the program after stripping the protection.

    So by forcing the attacker to a route where they MUST crack the executable, and then making it nearly impossible to crack the executable, I make a fairly formidable opponent in terms of protection for my program. Of course, after a given amount of time, presumably years, the protection scheme may be cracked wide open. But the entire point is outlasting the hackers until I can get a much newer version of my product, which will be protected with a much newer protection scheme. If the hackers want a product that’s been outdated for a couple years, be my guest.

  42. Michael Hubert April 11, 2010 at 3:24 pm #

    @Matt, your program might not have been specifically cracked, but I can confirm that PELock has been cracked, and any program protected with it can be easily unprotected if the attacker so chose to do so.

  43. Michael BT May 17, 2011 at 10:28 am #

    Michael Hubert hit the nail on the head. Modern protection is about running the program (or at least part of it) as a web service. Cracking assemblies and hacking servers are 2 entirely different games, and although your server may be hacked they’re playing in your backyard. It’s much easier to protect your server than it is to break an existing stand-alone program, and the degree of damage is determined by your vigilance in patching the server’s holes. In this scenario obfuscation hardly matters beyond renaming methods and variables because as Michale said they would have to rewrite the procedures themselves.

    Another method I’ve toyed around with is having a unique assembly for every machine. The installer reads unique values from your client’s machine and sends them to the server. The server then Modifies constants based on the unique IDs of the machine.

    ie. newConstant = originalConstant ^ uniqueID

    (calculated inline ofcourse)

    But even this is just another hindrance to the cracker whereas a web service is as close to perfection as one could hope to achieve. It really is about maintaining your control over the product.

  44. homework help November 5, 2011 at 4:26 pm #

    I have been exploring for a bit for any high quality articles or blog posts on this sort of space . Exploring in Yahoo I finally stumbled upon this site. Reading this info So i’m happy to exhibit that I have a very good uncanny feeling I came upon just what I needed. I so much indubitably will make certain to do not forget this site and give it a glance on a continuing basis.

  45. Hydroponics November 14, 2011 at 12:41 pm #

    I will right away snatch your rss feed as I can’t find your e-mail subscription link or e-newsletter service. Do you have any? Please allow me recognize so that I may just subscribe. Thanks.

Trackbacks/Pingbacks

  1. Everything you need to know about software registration systems « Digged Stories - September 6, 2006

    [...] read more | digg story [...]

  2. MyMicroISV » Everything You Need To Know About Registration Systems - September 6, 2006

    [...] Ed. Note: I was so impressed with Patrick’s post on what micro-ISVs need to understand about the registration process, I asked Patrick if I could reprint it here. The 10 comments his article got (so far) are almost as good!: read them here. [...]

  3. Increase Your Software Sales « MicroISV on a Shoestring - May 14, 2007

    [...] they’ll probably be good in years.  Some of my more popular posts here, for example on software registration systems, would have been topical ten years ago and will probably be topical ten years from now.  That post [...]

  4. The Piracy Loss Formula | Flowchart Dude - September 13, 2007

    [...] the correct formula, but also that nascent microISV’s are better off implementing their own simple licensing system than relying on 3rd party tools with potential side effects. Give a little link love:These icons [...]

  5. Why I’m Done Making Desktop Applications: MicroISV on a Shoestring - September 5, 2009

    [...] famously lackadaisical about software piracy, preferring to concentrate on satisfying paying customers rather than harming their experience with anti-piracy methods.  However, the existence of pirates [...]

  6. Types of Software Users « License Toolkit - October 2, 2010

    [...] McKenzie wrote a great blog post about software registration a few years back.  Patrick compares your software registration system [...]

  7. Lessons Learned At Business of Software 2010: MicroISV on a Shoestring - October 15, 2010

    [...]  (Not an issue in practice, you can pretty much fire-and-forget a low-pain DRM system, and since if you’re smart you’re doing web apps anyway this is disappearing from the [...]

  8. What’s the best way to protect a Windows application from piracy? - Programmers Goodies - July 5, 2011

    [...] http://kalzumeus.com/2006/09/05/everything-you-need-to-know-about-registration-systems/ [...]

Loading...
Grow your software business:
(1~2 emails a week.)