implementation for product keys [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm implementing a small application in C, which I would like to sell as shareware for a reasonable price later on. It will start of with a 30-day trial, which I am already quite certain of how to implement it.
The problem I have, though, is that I am not quite sure how to implement the product key verification. What I have in mind is that the customer can sign up on my webpage (after trying the product for a while), pay for the product, and get a product key in the form of aaaaa-bbbbb-ccccc-ddddd-eeeee via e-mail (or maybe available via his profile on my website). No problem so far. He/She then drops the key in the appropriate key fields in my app and boom the app is registered.
From what I could gather so far, people either recommend AES or RSA for this. To be honest, I in another direction in college (not cryptography) and the one cryptography class I took was some time ago. But from what I remember, AES is a symmetric encryption algorithm, which would mean that I would only have one key for encryption and decryption, right? How could I then generate thousands of product keys and still validate them in my app (which by the way won't require internet access....so no checking back with a server)?
So I guess RSA would be the way to go? But doesn't RSA produce pretty long keys (at least longer than the required 25 characters from above)?
In another thread I read that some products won't even use encryption for the product key generation/verification, but instead just employ some checks like "add the 2. and the 17. character and that should total to x".
What's the fastest, easiest and most secure way to go here? :-) Code samples would be sugar!
Regards,
Sebastian
P.S.: Oh...and please don't tell me how my key can and will be cracked at some point.....I know about that, which is primarily why I don't want to spend a lot of time with this issue, but at the same time not make it too easy for the occasional cracker.

Symmetric algorithms are limited, in that any novice cracker with a disassembler can find your key (or the algorithm used to generate one) and make a "keygen".
For this reason, asymmetric cryptology is the way to go. The basic premise is something like this:
When the user purchases a license from you, you collect certain identifying details about the user and/or their environment (typically, this is just a full name; sometimes a company, too).
You make a 128-bit MD5 hash of this information.
Using a 128-bit Elliptic Curve crypto, encrypt this hash using the private key on the server.
The 128-bit cipher text can be represented to the user as a 25-character string consisting of letters and digits (plus separating dashes for readability). Notice that 26 letters + 10 digits = 36 discrete values, and that 36^25 > 2^128.
The user types this product key into your registration dialog. The client software converts it back to a 128-bit number (16 bytes), decrypts that using the public key of your EC crypto, and compares the result to an MD5 hash of the user's personal information, which must match what was used for registration.
This is just the basic idea, of course. For more details and source code, see Product Keys Based on Elliptic Curve Cryptography.

Life is simpler if you simply purchase a solution.
http://www.kagi.com/kagisolutions/index.php
Kagi allows you to collect payments and they help you manage the keys.

A guy has blogged about how he handled the question of registration numbers. One of his blog entries is Generating Unique Registration Numbers.

Yes, RSA and AES are two very different things:
RSA is public key cryptography, involving a public key and a private key, and is fairly slow. The primary use is to set up a secure exchange of a symmetric encryption session key.
AES is symmetric encryption, which is fast and secure.
Since your app does not communicate over public channels and the use of cryptography is limited to product activation/registration you'll want to go with a symmetric cipher. The benefits of public key ciphers is in key management, which you will be handling on your web site or through email.
Note that you do not have to distribute the same key for every customer. You could generate a hash of some of the registration info and XOR it with something else (a fixed session key, perhaps). Send that to the customer, and the program could generate the same hash and XOR will the key you sent to produce the original fixed key.
Dealing with cryptography is not something to be done lightly. As you mention, you expect this to be cracked. If you're doing your own this will almost certainly happen. You can still use your own implementation to "keep honest people honest," but realize that's as far as you'll get. If you need something stronger then you should purchase a solution after doing thorough research on the solutions.

You can check out this Code Project article. It describes an implementation of a a software key based on the MAC address of the machine where the software is executed. The method is not ideal, as the auteur himself admits, and it is a little bit different from what you are looking for, but maybe it can help you.

Related

One way encrypting primary key

What is the best one way permutation function I could use to digest an e-mail so I can use it as a primary key without storing personal data?
I'm getting my first F2P game ready: a simple yet (hopefully) addictive 2D casual puzzler based on aiming mechanics. It's made with Unity and will be released on Android very soon.
In order for the player to keep the same data across different devices, I have an SQL table with the device e-mail as the primary key, then another string as the savegame data.
But I don't want to store the user e-mail for privacy reasons.
So I thought of digesting it with some function that would use the original e-mail to generate a new string that:
is unique (will never collide with another string generated from a different e-mail address)
is not decypherable (there should be no way to obtain the original e-mail from the digested string - or at least it should be hard enough)
This way I could still use the Android device e-mail to retrieve the savegame data, without storing personal data from the player.
As far as I've researched, the solution seems to be called a one way permutation function. The problem is that I can't seem to find an appropriate function on the internet; instead, all answers seem to be plagued with solutions for password hashing, which is very interesting (salting, MD5, SHAXXX...) but don't meet my first requirement of no collision.
Thank you in advance for any answer on this topic.
What you need is a cryptographic hash function such as SHA-256. Such functions are designed to be collision resistant, Git uses an older version SHA-1. Most languages/systems have support of this, just Google "Android SHA-256" along with your language of choice.
One option is to append a creation timestamp.
Update: Since SHA-256 does not provide sufficient collision resistance consider s GUID, from RFC 4122: "A UUID is 128 bits long, and can guarantee uniqueness across space and time.". Of course you need to find a good implementation.

Generate and/or validate license keys for App Engine for a closed beta

I will release my GAE application in a few months on a closed beta state, so that just a few users can use it and I get some date and know where and how to improve it. My idea was that I use a key system to let them access the application.
What I want to do:
I want to generate a punch of keys and store them with Datastore. When a users comes to the application the first time he logs in with his Google account and has to enter a key to activate his account.
My question:
My previous software didn't require such license keys or similar so this is a new area for me. Do you think this is good way to realize a closed beta? My second idea was to generate a bunch of keys and validate them with a system like other popular software does it, but I think this is unnecessary and I wan't to avoid a that someone can make a key-gen. Just generating, storing, then checking the key if it exists in the Datastore, setting it to used and activating the account would be my suggestion.
How can I generate a lot of valid and easily add more (without duplicates) keys. I'm thankful for every experience and suggestion.
As a refinement to Ashley's suggestion, if you'd like to generate shorter and/or easier to type IDs, you can generate some random data and encode it using base32:
base64.b32encode(os.urandom(8)).strip('=')
Make it a bit more readable by inserting hyphens:
'-'.join(base64.b32encode(os.urandom(8)).strip('=')[5*x:5*(x+1)] for x in range(3))
This gives you codes like the following:
'C6ZVG-NJ6KA-CWE'
Then just store the result in your datastore and hand them out to users. I'd suggest storing the code without the hyphens, and stripping those characters before checking the database. If you want to get really fancy, base32's alphabet is chosen to avoid characters that look similar; you could substitute those characters before you do the check to account for typos.
8 bytes of random data gives you 2^64 possible invite codes; if you hand out, say, 2^16 (65,536) of them, an attacker will still have to try 2^48 (about 300 trillion) codes to find a valid one. You can make your codes shorter at the cost of reducing the search space, if you want.
I use UUID for generating random keys:
UUID.randomUUID().toString().replace("-", "");
From the docs: "The UUID is generated using a cryptographically strong pseudo random number generator".
Generate a long list of them in the datastore, and then when a user arrives at something like: yourapp.com/betainvite/blahblahkey you can simply check if the key is in the table, and if it's rsvp property is null (or already set to the date it was used, in which case you deny the invite).
You could store the key against your User too, so you can find out who used each one and when.
Also good idea to maintain an invited date on the keys, then as you use each one you can mark it as invited, so you don't double invite people.

Do banks store passwords as plain text? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
I've seen some websites, particularly banking sites, that ask you to enter this (for example). Sometimes they ask for this to prove my identity over the phone.
The 2nd character of your password
The 5th character of your password
The 6th character of your password
To do this, a hashing algorithm won't work, would it? Surely something that should be as secure as a bank would have a way of storing the un-decryptable passwords?
Yes this can work without holding the plain text version of your password. Simply, when you originally set your password, the bank will hash the various combinations it will ever ask for, and store those hashes. This is very simple to implement, regardless of whether you have a fixed length password (i.e. a PIN number) or a variable length one. These hashes can be stored in a preset series of columns in the table related to the user, or as a simple 3 column table - ID (the primary key), UserId, Hash, and there is one row for each combination of n characters in your password.
I have doubts about the efficacy of this method over asking for the whole password though... maybe someone has a comment on that?
I would imagine they'd have some kind of private key system for decrypting (maybe even a private key per account, to improve security)...
It would be not too surprising, if (some) banks (or other big corporations) really stored plain-text passwords, or ROT13'd ones, or even double ROT13'd...
It's probably not a good item to discuss on an open forum, but what is to stop them from inserting your selected characters into a memory held, decrypted, copy of your memorable phrase or word at the appopriate locations, encrypting it and performing a binary comparison on the result?
They could just as easily keep a HASH of the single characters couldn't they?
You do NOT actually have to use a one-way HASH. You could just as easily use a two-way cypher, if you were certain that your key was secure. In this case they could easily keep the cypher on systems not accessible from the net.

Should I change my License Key output from pure md5 output to a common "XXXX-YYYY-ZZZZ" type code?

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?
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.
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.

How do you implement truncated sha1 database keys?

I'm working on a multi-tenant application that will be implementing service APIs. I don't want to expose the default auto increment key for security reasons and data migration/replication concerns so I'm looking at alternative keys. GUID/UUID is an obvious choice but they make the URL a bit long and while reading an article about them I saw that Google uses "truncated SHA1" for their URL IDs.
How does this work? It's my understanding that you hash part/all of the object contents to come up with the key. My objects can change over time so hashing the whole object wouldn't work since the key will need to remain the same over time. Could I implement UUIDs and hash those? What limitations/issues are there in using SHA1 for keys (e.g. max records, collision, etc.)?
I've been searching Google but haven't come up with the right search query.
/* edit: more information about environment */
Currently we are a Java shop using Spring/Hibernate with MySQL in back. We are in process to switch core development to Grails which is where this idea will be implemented.
I thought about a similar problem some time ago and ended up implementing Blowfish in the URL. It's not super safe but gives much shorter URLs than for instance SHA256 and also it's completely collision free.
That's actually a pretty solid idea, though it might make key lookups a little tough (unless you hashed the key and kept it inline in the table, I suppose). You'd just have to hash every key you use, though if you're auto-incrementing, that's no problem. You wouldn't even need a GUID - you could even just hash the key, since it's a one-way operation and can't be easily reversed. You could even "salt" your key before you hash it, which would make it virtually unbreakable by making the key unpredictable.
There is a concern about collision, but with SHA1, your hash is 160 bits, or has 1.46 × 10^48 unique values, which should be enough to support some fraction of that many unique keys without worrying about a collision. If you've got enough keys that you're still worried about a collision, you can upgrade to something like SHA256 or even SHA512, which should be plenty long as to avoid any reasonable concern about a collision.
If you need some hashing code, post the language you're using and I can find some, though there's plenty available online if you know what you're looking for.

Resources