English 中文(简体)
Generate reasonable length license key with asymmetric encryption?
原标题:

I ve been looking at this all day. I probably should have walked away from it hours ago; I might be missing something obvious at this point.

Short version: Is there a way to generate and boil down an asymmetrically encrypted hash to a reasonable number of unambiguous, human readable characters?

Long version:

I want to generate license keys for my software. I would like these keys to be of a reasonable length (25-36 characters) and easily read and entered by a human (so avoid ambiguous characters like the number 0 and the capital letter O).

Finally--and this seems to be the kicker--I d really like to use asymmetric encryption to make it more difficult to generate new keys.

I ve got the general approach: concatenate my information (user name, product version, a salt) into a string and generate a SHA1() hash from that, then encrypt the hash with my private key. On the client, build the SHA1() hash from the same information, then decrypt the license with the public key and see if I ve got a match.

Since this is a Mac app, I looked at AquaticPrime, but that generates a relatively large license file rather than a string. I can work with that if I must, but as a user I really like the convenience of a license key that I can read and print.

I also looked at CocoaFob which does generate a key, but it is so long that I d want to deliver it as a file anyway.

I fooled around with OpenSSL for a while but couldn t come up with anything of a reasonable length.

So...am I missing something obvious here? Is there a way to generate and boil down an asymmetrically encrypted hash to a reasonable number of unambiguous, human readable characters?

I m open to buying a solution. But I work on a number of different of platforms, so I d want something portable. Everything I ve looked at so far has been platform specific.

Many, many thanks for a solution!

PS - Yes, I know it will still be cracked. I m trying to come up with something reasonable that, as a user, I would still find friendly.

最佳回答

Unfortunately, no. If you make it shorter, you lose information and won t be able to recreate the original hash.

However, here s a couple things you may try:

  • Use base32. Map it to all the available letters in the alphabet that aren t ambiguous. (0vsO, etc.)
  • Use DSA, it tends to be more compact than RSA.
  • Making your input shorter (truncating the sha1 hash, or using md5 instead, for example) might make the output shorter, too.
问题回答

Treat each SHA1 character as hex, perhaps drop any unnecessary formatting, (dashes or brackets), use some array mapping to convert 0-9A-F as say A-P in some random order, use that as your human entered text. MD5 will give you your 32 chars or a few more for SHA1. Unmap the chars back to your SHA1/MD5 string/bytes and proceed from there.

I will not answer on the encryption part, but the thing I have started to do registration interfaces is to check the clipboard for text when the interface is raised. If text is present on the clipboard, scan it to see if the user has copied their registration information from somewhere (email, web page, etc.) and if you find information that could be your registration info/keys, pre-populate the registration interface with it.

It is also a good idea to show a small alert on the interface indicating that the info was successfully scraped from the clipboard (or not!) just so the user knows what did or did not happen.

The best signature based method to create short license keys currently seems to be the Boneh–Lynn–Shacham signature scheme, though it is rather recent (not so many reviews) and not implemented in common crypto tools.

Here is a way to do it with generic openssl and bash:

openssl ecparam -genkey -name sect113r1 -out private.key # generate the private key (store it on your server)
openssl ec hist-in private.key -pubout -out public.key # generate a public key (store it in the client software)
# generate a random one time activation userID or a hardware-based one here (CLIENT SIDE)
user_id="unique_on_the_fly_generated_user_ID" # send the user ID to the server for license generation
signature=""
return_value=0
while [[ $return_value == 0 ]]
do
    signature=$(echo "$user_id" | openssl dgst -sign private.key | base64 > signature.txt) # generate a user licence
    echo "$signature" | egrep -q  O|l|/|+|=  # check for ambiguous chars
    return_value=$?
done
echo "$signature" | base64 -d > signature.txt # send the signature/license to the client
openssl dgst -verify public.key -signature signature.txt # verify signature (CLIENT SIDE)

Note that you still get a 48 characters long signature/licence key (plus a generic "M" header char you can avoid sending). As far as I know you can t generate shorter signatures with openssl at the moment.

I would consider the MD5 algorithm. It s widely implemented and will generate a 32 character alphanumeric string regardless of the input size. Apply the algorithm to your SHA1 hash and it may be what you re looking for.





相关问题
How are software license keys generated?

License keys are the defacto-standard as an anti-piracy measure. To be honest, this strikes me as (in)Security Through Obscurity, although I really have no idea how license keys are generated. What is ...

Encoding license file for privacy

We re using XML Digital Signatures for signing and verifying our license keys. The signing works fine and has been running smoothly. The XML license file contains a few (plaintext) details about the ...

License key pattern detection? [closed]

This is not a real situation; please ignore legal issues that you might think apply, because they don t. Let s say I have a set of 200 known valid license keys for a hypothetical piece of software s ...

How to prevent a file from being tampered with

I want to store confidential data in a digitally signed file, so that I know when its contents have been tampered with. My initial thought is that the data will be stored in NVPs (name value pairs), ...

热门标签