My name is Kenneth and I write cool Mac and iPhone software. This is my personal weblog where I post about stuff I find interesting. I usually write about Mac development, the business of shareware and the Mac community in general.
read more →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:
- The ASCII value of the first character of all five blocks of four characters have to add up to 100.
- The last character of all five blocks of four characters have to be vowels.
- The first character of either block 3 or 4 has to be E.
- The ASCII value to the third character of every block have to be even numbers.
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!
[…] Kenneth has put together a piece on serial number generation. […]
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.
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.
@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.
How would you implement this into your application?
I am confused please help. If you know of any easier ways please let me know.
@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.
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?