Licensing State of the Union

(This is a guest post by my friend Nick Paulson @ who is a Cocoa Developer working on various cool things including CloudApp.)

As a developer, I want to keep my applications safe from piracy. Itʼs always a predicament to find a solution that will not bother your real customers. We are going to look into some common licensing schemes, but before we do, letʼs make sure we are all on the same page.

Definitions

Serial Sharing
Giving a serial number to a friend or a group of friends that use it beyond the purchased license count. This can be done by both sharing the serial number itself or by sharing the preferences property list file that is most commonly found in ~/Library/ Preferences/.

Cracking
Also known as patching: changing certain bytes in an application in order to make it think itʼs registered at all times. It also includes the app being changed in a way so that it accepts any registration information. Every application update has to be cracked individually, it does not carry over version to version.

Keygenning
Creating an application that generates serial numbers. This is done by inspecting what an application checks for in a serial and then producing serial numbers that will validate under that scheme. For example, a serial might be considered valid if it is 5 characters long and the first character is A and the third character is 1. Therefore, a pirate would create an application that creates serial numbers that follow that scheme, such as A21GD, AQ111, etc. Keygens are overall the worst thing that can happen to your application because you cannot differentiate between a serial number that is legal and one that is illegal, except using a purchased serial number database.

RSA
An acronym for Rivest, Shamir and Adleman, the original creators of RSA. It is a form of cryptography that uses a pair of private and public keys to encrypt and verify data. A message sent encrypted using the private key will only decrypt properly with the public key, which makes it possible to verify that the sender of the message is who you truly believe they are. Licensing schemes sometimes use RSA in order to confirm that licenses only came from the application developer, and not a pirate.

Now that that is out of the way, on to the schemes.

Offline Activation

This is the most basic of licensing schemes. It involves the user inputting a serial number with an optional name or email address, and verifying it locally on the userʼs computer. It is vulnerable to all forms of piracy because the verification schemes are available for the pirate to reverse engineer and there is no checking against a purchased serial database. Blacklisting can be implemented to stop rampant serial numbers, but because it vulnerable to keygenning, blacklisting can only go so far.

Though it is vulnerable, it does not bother real customers. It is a great solution if you are confident in your application and arenʼt concerned with piracy.

Online Activation

Online activation is the next step up from offline. It verifies the serial number over the internet in order to prevent people from sharing their licenses. If a license were activated 500 times on 500 different computers, obviously the license is being shared. Online activation makes it easy for a developer to blacklist serial numbers on the fly. Usually the verification is done by loading a URL such as https://myawesomeapp.com/verify? user=nickpaulson&serial=THIS-ISMY-LICE-NSE1 and reading the response. The responses can be many different things, but two are most common, with one being more secure than the other.

The first is by returning plaintext information about the result of the verification. It could return something like “status: success” or “status: blacklisted”.

There is a problem, however. Once the serial number is verified, it is most likely going to be placed in the applicationʼs property list so it can be verified locally on the next startup. It would be a burden on the user to have to verify their serial number with the server on each startup, especially if they are trying to run it without an internet connection. Therefore, this method is vulnerable to serial sharing, cracking, and keygenning. A keygen can be created that generates a serial number and then writes it to the applicationʼs preference file. This bypasses the internet verification completely. The userʼs preferences file can also be shared, and a crack can be made by changing (usually) just a few bytes.

The second response is something more complicated, but also more secure. Instead of returning a simple string, it can return an RSA-encrypted message containing the result of verification along with the serial number. If this cannot be decrypted, then someone else must have created the message artificially, and it therefore must be invalid.

Instead of writing the serial number to the preferences file to be verified on startup, the RSA-encrypted message would be. On the next startup, if the message in the property list fails to decrypt, someone was messing with the license. Because the RSA- encrypted message cannot be created by a third-party, this method is not vulnerable to keygenning. It is, however, vulnerable to serial sharing (via a shared preferences file) and cracking.

Third-Party Solutions

Many companies provide licensing schemes for a cost. Two examples of such companies are Kagi and Esellerate. There is also a free, open-source solution named Aquatic Prime. Letʼs take a quick look into how they work.

Kagi & Esellerate
These companies provide a framework or library to be included in your application. They supply you with a unique identifier that is used to verify licenses. It is a quick and simple drop-in solution for your application, and they also handle payment processing for you. However, there are some rather large drawbacks to using these companies. It is very obvious to a pirate that you are using Kagi or Esellerate, and it makes the stealing processing much easier for them. Once the generic algorithm for verification is reversed to create serial numbers, your application, along with all others that use Kagi or Esellerate, are instantly vulnerable. It is not difficult for a pirate to find the identifier in your application, and stealing your application becomes very simple. As a result, Kagi and Esellerate are vulnerable to cracking, serial sharing, and keygenning.

Aquatic Prime
Aquatic Prime is an open-source framework for the creation and verification of licenses. It provides an application that developers can use to generate licenses, along with a framework that can be dropped into an application for license verification. It is RSA-backed, which adds to license security. But donʼt be deceived, Aquatic Prime is quite vulnerable. First off, like Kagi and Esellerate, it has a generic scheme with a unique identifier. In this case, the unique identifier is the RSA public key. This generic scheme is very easily patched by pirates. Also, if the framework is linked instead of compiled inside the application, a pirate can just replace the AquaticPrime.framework in the application bundle with his own. He or she might force all licenses to verify as correct or even hardcode a different public key inside so they can generate their own licenses. Therefore, Aquatic Prime is vulnerable to serial sharing (sharing the license file), and cracking, and a keygen+crack combo.

DES3 Protection Caution: Advanced Topic

This is a form of application protection that, while not widely used, is interesting to take a look at. DES (which stands for data encryption standard) is a form of encryption/ decryption that uses a secret key. One way to use DES3 in an piracy protection scheme is to use it for application integrity. For example, you could create a plist file that contains some constants as keys along with class names or selector strings as their values:

NP_SEARCH_FIELD: NPSearchField
DO_FILE_UPLOAD: doFileUpload

Once the application has been compiled and is ready to ship, the property list can be encrypted using the SHA1 value of the application binary. This can be calculated using the following command in Terminal:

openssl sha1 /Applications/MyAwesomeApp.app/Contents/MacOS/MyAwesomeApp

Then the property list can be encrypted using the following command:

openssl des3 -k -in Secrets.plist -out Secrets.encrypted

Then, put that file in the application resources folder and make sure the unencrypted property list file is not inside.

On the application side, it should calculate the SHA1 value of the application binary using a third-party framework (such as SSCrypto.framework) and then create an NSTask object that does the following command:

openssl des3 -d -k -in Secrets.encrypted -out Secrets.decrypted

Read the property list into the application, get the needed constant, and return to the workflow. Make sure to delete the decrypted file when completed. If the property list fails to decrypt, the constant will not be returned and cause some application functionality to cripple. Basically, if even one byte is changed in the application binary (such as, for a crack), the application becomes crippled. This will help to hinder pirates from cracking your application, but it does not prevent it whatsoever. It will also slow down your application quite a bit depending how many constants you use, because the decryption must be done each time it is loaded. So this method will hurt your real customers.

You may be asking, “how can this be cracked?” Basically, the pirate decrypts the encrypted property list file and replaces the encrypted one with the newly decrypted one. After, he NOPs (no operation) the decryption process, so the application essentially just loads the “encrypted” file into memory, and then converts it to a property list without decryption. Because it is already decrypted, this works fine and the piracy protection has been broken.

Conclusion

There are a number of ways to protect your application from piracy. However, when it comes down to it, piracy cannot be stopped. Whether you like it or not, if someone wants to steal your application, they will. On this note, pirated copies should not be considered lost sales. Most pirates had no intention of purchasing your application in the first place. Donʼt hurt your real customers. If your application is good enough, people will buy it. The best way to prevent piracy?

Make great apps.

Featured Project

Design Then Code