# Creating a license system based on asymmetric encryption (RSA or ECDSA)

I’ve spent a couple of days researching the topic of creating a license system for my desktop software. While I fully understand that there’s no perfect copy protection, this approach seems to have the best balance for me. There are a couple of details that I can’t fully get my head around before starting with the implementation. I’d really appreciate if you could share your thoughts on the following topics:

1. Encrypt or Sign? (answered -> sign)

In my understanding both encrypting and signing the license information on my server-side with my private key would work. The desktop client would either have to decrypt or verify the signature of the license text-file with the embedded public key. The only difference I see is that in the latter case the content of the license file is humanly readable while the encrypted version is not. Would you rather encrypt or sign the license file? Why?

2. Hash or directly encrypt/sign the License? (answered -> signing automatically hashes it)

Let’s say the license information text consists of about 300 bytes. Would you recommend to sign/encrypt it directly, or hash it and then sign/encrypt the hash? I’m asking this because I’ve read different statements that asymmetric encryption isn’t suitable for large data. But what’s the limit?

What’s the best way to revoke an already issued license? I understand that having an online blacklist is probably the most accurate solution, however I don’t want the software to be dependent on an Internet connection and the reliability of my server. So I guess the alternative is to have black-listed licenses within the application being maintained with new releases? In that case what exactly would I create a list of? The signed/encrypted license (probably too big with a growing list)? A hash of it? Something completely different?

Edit: Combining the replies so far I guess the first two questions can be combined to "Sign it and don't care about the content length".

The third question however remains unclear to me. I'd like to point out that I don't want to have a dependance on an online server for not bothering honest customers. After all forced online connections bring more annoyance than security. So there needs to be kind of an "offline solution", even if less secure. Please reconsider question #3 under this aspect.

Actually I'd even like to extend question #3 by the following scenario:

4. Replace stolen/hacked private key In a worst case scenario the private key might get stolen or somehow hacked, so the attacker is able to create a license generator himself. What would I have to do in this case? I can't blacklist some licenses like in #3, so instead I'd have to replace the key pair, wouldn't I? However in my understanding that would also mean that all customers would require to receive new licenses when updating to a new version with the replaced public key. Is there some clever solution for only blacklisting licenses with the old key pair that have been created after a certain date so the already created licenses before some date stay intact? I understand that it'd require some kind of timestamp system that an attacker can't fake. Is there such a thing?

Thank you!

-
No, I mean that in case I find out that a license is being abused (e.g. shared on the Internet) I'd like to invalidate/revoke it. I'll edit my question accordingly. – CodeX May 31 '14 at 11:45
For scenario #4, approach that is simple and has been used in practice is whitelisting. Note: The whitelist can get very large. – user4982 May 31 '14 at 16:49
@user4982 What exactly would I whitelist? The issued licenses? In that case I'd have to release a new version of the software after each purchase!? – CodeX Jun 1 '14 at 17:19

Sign the license text. There's nothing confidential in the license text, so you don't need confidentiality.

If possible, include some kind of customer ID or something in the license that links it to a particular customer.

Standard digital signature schemes can easily sign arbitrary-length messages. Don't worry about the length of the message. (Internally, they hash the message with a collision-resistant cryptographic hash, then sign the hash, roughly speaking, which is how they can handle arbitrary-length messages efficiently. But you shouldn't need to know that, if you are using a standard implementation of a well-vetted crypto algorithm.)

One approach to revocation is to have your client software contact a central server for periodic download of the revocation list. The alternative is to have your server issue short-lived signed authorizations, and require the client to periodically contact the server when each one expires to get a new one (and the server can withhold providing any new authorizations once you revoke that customer). In either case, make sure that the client can continue to use your software for some set period while they are offline without destroying their access to the software, or your customers might become very mad at you.

There is no purely offline solution to revocation. If the customer has no network connectivity, there's no way to revoke their software license early. If in the absence of revocation their software license would be valid until time $T$, and at time $t<T$ you want to revoke them, you can't. Consider: from the client's perspective, there is nothing that lets them distinguish between whether they are revoked or not, if they don't have any communication whatsoever with the server or anyone else. So if you expect clients to be offline, it becomes a tradeoff between "the lifetime of a license" (how long before it expires?) vs "speed of revocation" (how long before revocation takes effect?). If you issue licenses that are good for one year, then revocation won't take effect until that year is up -- if clients are offline.

What you can do is refuse to provide software upgrades to clients whose software has been upgraded. This won't prevent them from continuing to use the older version of the software, though, for as long as their license is valid. Optionally, you could also have the client software try to connect to the Internet whenever possible, and if the client goes for a certain time period without having being able to reach the server, you could have the client disable itself; whether this is acceptable will depend upon how you expect your legitimate customers will use your software.

If your private signing key is stolen, you are hosed. There's nothing you can do to prevent whoever holds that signing key from generating illegitimate licenses that the existing version of your software will accept as valid. All you can do is change the public key that's hardcoded into the software, in the next software update (so people won't be able to use that newer version of software using licenses signed by the old stolen key) -- but this won't stop people from using the older version of your software. So try to not let your signing key get stolen.

Finally, remember that these licensing schemes provide a speedbump, not strong security. They exist to keep honest people honest, but they will not be effective at deterring or stopping dedicated malicious people from bypassing your copy protection system. Therefore, whatever you do, try to ensure that your license system doesn't inconvenience honest users too much. Don't drive them to download pirated copies because they're less annoying than the actual paid-up copy.

-
I fully agree with you. You basically confirmed my personal thoughts which makes it easier for me to proceed. Also you’re right that I shouldn't need to know the technical background, but to create a solid solution it really helps to have a good background understanding. If possible please have another look at my question #3 again as it remains unclear to me. I actually extended it with a related question #4. I’d like to hear your thoughts about this. – CodeX May 31 '14 at 13:38
@CodeX, sure. I expanded my answer to elaborate further on revocation (your question #3) and stolen private keys (your question #4). – D.W. May 31 '14 at 18:22

First off: if you sign the licensing information server-side what keeps hundreds of users from using the same license? I´d rather create asymmetric key pairs and provide the private key along with an ID as the license code. The client can then proove to the server that it owns a valid license. This already ansewers question 3: revoking a license can be easily done server-side. Also, preventing a software from going online is a lot harder than provide a working serial. (while still easy for the ones who know how).

For question 1: I think signing is the best option when working in the way i described above.

This also answers question two: when the client needs to proove to your server that it owns a valid license, only a small amount of data needs to be signed. This can be a fixed number, e.g. $e^{20}$. Hashing is not required. You could even leave the padding since buying your software is most likely cheaper than the easiest attacks on a cryptographic key.

P.S.: Most serial codes consist of about 24 characters. In Hex-Notation this only gives you a 96 bit key. However, if you encode it base-36 (so 0-Z), you can fit 124 bit into 24 characters.

-
If you "create asymmetric key pairs and provide the private key along with an ID as the license code" $\hspace{.17 in}$ "what keeps hundreds of users from using the same license" code? $\;$ – Ricky Demer May 31 '14 at 0:55
By not accepting the license code if another program with the same id is already running. – marstato May 31 '14 at 12:57
That would make it an "always on" software, which in my experience every user (including me) hates. I'd like to have a reasonable protection while not annoying honest customers. – CodeX May 31 '14 at 13:30
@marstato : $\:$ Anyone could just change the ID, since it's not tied to anything else they have. $\hspace{.85 in}$ – Ricky Demer May 31 '14 at 14:57
@CodeX: if the software cannot connect to your server you just consider the license valid. RickDemer: The ID is tied to a license. The software sends its ID and signed data, the server checks the signature with the correspponding public-key. – marstato Jun 1 '14 at 20:35

The problem with DRM is that the keys must be revealed to the end user machine and thus susceptible to interception. Not to mention I believe that the Sony PlayStation uses ECDSA to secure its firmware and it got cracked.

-