One challenge that most developers face when nearing release of their first application is how to implement registration and piracy protection. This three-part article will describe three common types of registration schemes: Serial Numbers, Asymmetrical Cryptographic Keys and Product Activation.


Part One: Serial Numbers

Serial numbers are the simplest, most practical option. However, they are also the least secure. It consists of taking at least one of the customers’ details, and creating a serial number from it. The serial number is usually tied to either the customer’s name, or his email address, preferably both.

For example, let’s say the customer’s name “First Last” and his email address is “email@address.com”. The first step would be to strip his name and email address of any non-alphabetical characters, concatenate it and convert it to uppercase. (I put the email address first, because it’s less recognizable) Here’s what we get:

EMAILADDRESSCOMFIRSTLAST

Now map this string onto a XXXX-XXXX-XXXX-XXXX-XXXX key. If there are any character leftovers, just discard them. If there aren’t enough characters to fill all the Xs in, leave them as something constant. (they don’t have to be all the same, but they have to be the same for each position all the time. You could for example say you’re mapping it onto an QRST-ABCD-IJLK-EFGH-MNOP key, and leave unfilled spaces as is)

EMAI-LADD-RESS-COMF-IRST

Then, we’d apply ROT13 on it.

RZNV-YNQQ-ERFF-PBZS-VEFG

Lastly, we could replace any swearwords in the key by some random other constant text, just in case.

Another example, using a similar method: Using the same customer, here’s what we’d do. Take his details, concatenate and salt them:

First Last+random salt+email@address.com

Then, MD5 the result and add another salt:

salt+0fb61d4a0f894c63d3ddbd8388404b6c

Next, SHA1 the result:

28a8275bdcbca542f567efef9cc4db2150c38900

And finally, uppercase it and map it onto a XXXX-XXXX-XXXX-XXXX-XXXX serial:

28A8-275B-DCBC-A542-F567

When you have decided on a serial scheme, implementing it is easy. Upon registration, you take the buyer’s name and email address, and generate a serial from it. He then has to input this serial into you app, along with his name and email address. All you have to do in you app is take the name and email address he gave you, generate a serial from it, and check it against the serial he gave you.

Making it more secure

For security reasons, one important step to take is obfuscating how you create those serials, in case anyone tries to create a keygen for you app. The easiest way is adding dummy maths code in the middle of the code where you work out your serial. It will not affect your serial, but it will show up in the assembly code in case anyone tries to gdb your app (more on that in another blog post I have planned).

Another quick thing you could do is shuffle the characters a bit on a set pattern to make them less obvious.

For example you could use this pattern:

ABCD-EFGH-IJKL-MNOP-QRST

becomes

TMLN-DQGA-ISPC-BEOK-FJRH

Stand-alone serials

Sometimes, your serials cannot be tied to any of the customer’s data, for example for retail sales. In that case, you’d need a different serial scheme. You need to choose certain characteristics / rules that make a serial valid. It could be as simple as checking that the 19th character is a W.

Here’s a set of example rules you could use:

In your apps, just check the serial against the rules, and if it’s correct, you can assume it is a correct serial.

For your generator, you can have a pre-made list of valid serials, and assign them to a customer or print them on a retail copy when needed. The problem with this method is that you can eventually run out of valid serials. In which case you would have to generate a new batch of serials, or reassign already used serials to a second customer.

Another (better) way of doing stand-alone serial numbers is splitting the serial number in two, and basing the second part on the first part. [thanks to tomasf from the #macsb IRC channel for this method]

For example, in a serial number ABCD-EFGH-D07A-A959-F269, separate the first eight characters from the rest of the serial:

ABCDEFGH

Salt it:

saltyABCDEFGH+123

MD5:

d07aa959f269104ab28e2a748c415c5c

Map it onto XXXX-XXXX-XXXX:

D07A-A959-F269

And check it against the second part of the serial. In this example, the serial is correct.


Part Two: Asymmetrical Cryptographic Keys
The last parts will be coming soon.


This entry was posted on Thursday, April 3rd, 2008 at 11:26 pm and is filed under Articles, Business, English, Hacking, Programming. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
Add your thoughts!
7 Comments
April 3rd, 2008 at 11:43 pm

[…] Kenneth has put together a piece on serial number generation. […]

April 4th, 2008 at 1:36 am

I work for an anti-piracy company.

Unless you tamper-proof your code, you’re guaranteed a keygen.

I wouldn’t use the above scheme for a product costing > $100.

April 4th, 2008 at 4:20 am

You really lose all credibility by even mentioning ROT13 in the context of this conversation. And the arbitrariness of MD5-ing then SHA1-ing the data just boggles my mind.

This doesn’t really encourage me to use your encryption product.

/me checks posting date, nope two days too late.

I hope parts two and three of this series merely tell your audience to go use Aquatic Prime.

kenneth shrieks
April 6th, 2008 at 12:46 am

@pierce: I totally agree with you. In fact, the next two parts (the first of which I just posted) describe better techniques for more expensive products.

@jonathan: I really don’t know what you dislike about this article. It describes the theory behind serial number, and simple examples you can mangle to get this type of serial numbers. You mention the arbitrariness of using MD5 followed by SHA1. But the whole point behind this type of serial is to have an arbitrary obfuscated way to generate innocent-looking serial numbers.

The Joe bro moans
April 9th, 2008 at 3:12 pm

How would you implement this into your application?
I am confused please help. If you know of any easier ways please let me know.

July 10th, 2008 at 12:58 pm

@The Joe bro
Simply create an algorithm in your application that parses the person’s first and last name and email and after running it through the algorithm check to see if the serial you gave the person is the same as the one they entered.

Michael Fisher moans
February 9th, 2012 at 1:54 am

A few years late to comment… I want to mention that, despite what some others said, this article *IS* useful and very informative. Especially for people who have never coded this type of thing before.

And as far as ROT13 is concerned, I think that is a good way to improve the appearance of a serial ( nothing more than that though ). Meaning a serial that consists of nothing but md5 and sha1’s are only going to give you A-F. Rot13 will roll those over to letters greater than that.

Anyway, thanks for the info!


Have something to say?