1

I'm creating a simple license key system to "keep honest people honest". I don't care about especially stringent cryptography.

If they get to annoyed with the demo limitations, they go to my registration website, pay, and give me their email. I give them a license key.

I'm keeping things really simple, so:

license_key = md5(email + "Salt_String");

I have PHP and C# functions run that same algorithm and get the same key.

The problem is that the output of these functions is a 32-character string like:

A69761CF99316358D04771C5ECFCCDC5

Which is potentially hard to remember/type. Yes, I know about copy/paste, but I want to make it REALLY easy for all paying customers to unlock the software.

Should I somehow convert this long string into something shorter?

Lets say I use only the first 6 digits, so: A69761

There are obviously way more cryptographic collisions in that, but will it matter at all in practical use?

Any other ideas to make the thing more human readable/typeable?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
ck_
  • 3,719
  • 10
  • 49
  • 76

2 Answers2

3

To left 6-10 symbols will be enough - the user anyway will not be able to guess the code, and it would be easy to type in. Also good idea would be to register each license on your server, so that you will be able to check that user is really honest, and didn't give a license key to another person.

Nickolay Olshevsky
  • 13,706
  • 1
  • 34
  • 48
  • By "register each license on your server" do you mean the app should 'phone home' every time it connects? I'll probably avoid that for the time being, as I assume that real crackers will be able to get around that too. – ck_ Jan 12 '11 at 18:19
  • And thanks for reassurance on only using the first 6-10 symbols. – ck_ Jan 12 '11 at 18:21
  • "register each license on your server" - no, I mean only the time when user enters license information into app. That would help against giving license key to friend, of course not against real cracker – Nickolay Olshevsky Jan 12 '11 at 20:15
1

In my experience, asking the user to type or copy/paste a 30-character code indeed leads to frustrated customers. It's not that it's so difficult. It's simply a hurdle that people don't care for.

The solution I've used for my business is to have separate trial and purchased downloads. To get their licensed copy, the customer types in their email address and a short user ID on the download form. Entering only the email automatically resends the user ID. You didn't ask about this, but a system to automatically look up whatever code the customer needs is even more important than having a simple system. The download system looks up the user's details in the database and serves a SetupSomeProductCustomerName.exe that has the user's license embedded in it. This setup installs the customer's licensed copy without requiring any further identification or server connections.

This system has worked really well for us. The customer has only one file to back up and no serial numbers to lose to make sure they can reinstall the software in the future.

That said, if you prefer to use a system using a one-way hash, simply use an algorithm that generates a smaller hash. E.g. CRC-32 results in 8 hexadecimal digits.

There's no point in the hash being cryptographically secure. A cracker will simply walk through your code, copy the entire block of code that mutates the email address into the license key, and paste that into their keygen. Then they can generate license keys for any email address. They can do that regardless of how complex your hashing algorithm is.

If you want to prevent this, you need to use public key encryption, which results in keys that are far too long to type in. If you go that route, you'll either need to annoy your customers with long keys to paste in or separate key files, or use the personalized download system I described above.

Jan Goyvaerts
  • 21,379
  • 7
  • 60
  • 72
  • How do you handle people with the trial installed then having to uninstall/reinstall to get the full version? I would think one download that can be unlocked to full would require less support, not more. And the full version has NO licensing system? Seems worse than keygens, which are still a bit of an annoyance/deterrent. – ck_ Jan 12 '11 at 18:27
  • Also, is there good reasoning for "casual validation" (not secure cryptography) to use something like CRC-32 rather than md5 shortened to 6-10 characters? Will both be 'good enough'? Getting the C# and PHP md5 functions to match was kind of time consuming, so I'd rather not redo it :) – ck_ Jan 12 '11 at 18:29
  • CRC-32 is a very poor choice - it's intended as a checksum to detect transmission errors, and it's trivially broken. A shortened secure hash is a better idea. – Nick Johnson Jan 12 '11 at 23:28
  • @cksubs: The user does not have to uninstall the trial. They simply install their licensed copy which automatically replaces the trial. We get about one complaint a year about having to redownload. The full version does have a licensing system. The setup is named SomeProductCustomerName.exe and the customer's name and email address are shown in the about box. Yes, the customer can distribute their licensed copy. That's no different than people sharing their registration codes. The only way to stop that is with online activation. – Jan Goyvaerts Jan 18 '11 at 13:49
  • @Nick: All one-way hash algorithms are a poor choice for license keys. In order for the software to validate the key entered by the user, the software needs to contain the whole algorithm and the salt. The crackers just step through the disassembly with a debugger, and copy/paste the whole thing into a keygen. It doesn't matter how strong your lock is when the crackers know the key is under the doormat. The only way to prevent keygens is to use public key encryption so that the private key is not in the software and thus can't be copied into a keygen. – Jan Goyvaerts Jan 18 '11 at 13:55
  • @Jan There's such a thing as better choices and worse choices. There's absolutely no sense in picking a hash function that's trivially reversed - CRC32 is not designed for security - when you could as easily use a secure hash function. To use your lock analogy, this is like using a child's toy padlock instead of a real lock - the attacker won't even have to bother looking for the key. – Nick Johnson Jan 18 '11 at 22:29
  • @Nick: A cracker never finds himself with a serial number (hash) that he has to figure out the license name (plaintext) for. So it doesn't matter whether the hash is reversible. The license name is always known (whatever handle the cracker wants to register the software to). The serial number is unknown. To get it, the cracker steps the software through a debugger and lets the actual software generate the serial. It really doesn't matter what the algorithm is. – Jan Goyvaerts Feb 24 '11 at 05:42
  • @Nick: When I suggested CRC-32 I didn't mean to say that it is a good hashing algorithm. I meant to say that whatever algorithm you choose, secure or not, your software will be cracked using the same method the crackers always use. The only way to prevent keygens is to use public key encryption. Arguing about better ways to generate serial numbers without using public key encryption is pointless. – Jan Goyvaerts Feb 24 '11 at 05:46
  • @Jan I agree that using public key crypto is a better idea. The fact remains that suggesting CRC32 - a checksum function - as an alternative is a bad idea, because it doesn't have the properties you need. There's absolutely no reason to use it instead of something better like SHA-1. – Nick Johnson Feb 25 '11 at 02:11