One challenge that most developers face when nearing release of their first application is how to implement registration and piracy protection. This three-part article will describe three common types of registration schemes: Serial Numbers, Asymmetrical Cryptographic Keys and Product Activation.

Part Two: Asymmetrical Cryptography

Asymmetrical Cryptographic Keys are a great way to secure you app, because the code used to generate serials is not included in your app, thus removing the risk of a keygen. Using a private key, you sign (or encrypt) some of the user’s details. You then use this singed data as the key to your software, either in the form of a serial, a file, or even an image with the data embedded. You then verify that the signature is valid using the public key in your app.


Start off by generating a set of private and public RSA keys. You can do this by using the following in

openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -out public.pem -outform PEM -pubout

You can use different size keys. Using a shorter key, such as 512 will make your software more vulnerable to brute-force attack, but has the advantage of making the signature smaller (Which is useful if you wish to display it in the form of a Serial Number).

I believe I used the following set of keys. The keys are also included as files in the source code of this example (available at the bottom of this article).

-----END PUBLIC KEY-----

Next, we will create the generator. We will start by concatenating the details (full name and email address) into a single string:


Then, we will use RSA to sign this string using the private key generated above:


Note: for this sample app, I explicitly turned off creating newlines in the base64 signature.

The code used for this generator is:

    NSData *privateKeyData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"private" ofType:@"pem"]]];
    NSData *publicKeyData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"public" ofType:@"pem"]]];
    NSString *details = [NSString stringWithFormat:@"%@+%@", [name stringValue], [email stringValue]];

    SSCrypto *crypto = [[SSCrypto alloc] initWithPublicKey:publicKeyData privateKey:privateKeyData];
    [crypto setClearTextWithString:details];

    NSData *signedTextData = [crypto sign];
    NSString *string = [signedTextData encodeBase64WithNewlines:NO];

    [serial setStringValue:string];

    [crypto release];

As you can see, I used Septicus Software’s great SSCrypto framework for this task… It makes things so much easier… Unfortunately it doesn’t support base32 or DSA, which would both have helped make more human-friendly keys.

The other piece needed is the validator, used in your software to validate serial numbers. Include only the public key in your app, and use RSA to verify the key.

    NSData *publicKeyData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"public" ofType:@"pem"]]];
    NSString *details = [NSString stringWithFormat:@"%@+%@", [name stringValue], [email stringValue]];
    NSData *number = [[[serial stringValue] dataUsingEncoding:NSUTF8StringEncoding] decodeBase64WithNewLines:NO];

    SSCrypto *crypto = [[SSCrypto alloc] initWithPublicKey:publicKeyData];
    [crypto setCipherText:number];

    [crypto verify];

    if([[crypto clearTextAsString] isEqualToString:details])
        NSRunAlertPanel(@"Result", @"Good serial!", @"OK", nil, nil);
        NSRunAlertPanel(@"Result", @"Wrong serial!", @"OK", nil, nil);

    [crypto release];

Important Note: In this sample code, I included both the generator and the validator in the same application. I included the private.pem file in the bundle. You should never do this. If the private key is ever leaked, it compromises the whole security of your application.

Making it safer

You can easily make it more secure by combining this technique with the technique explained in Part One. Instead of simple concatenating the details as I did here, you could use all the techniques applied in Part One, such as using a hash instead, or doing ROT13 on it, or rearranging the order of the characters.

Another thing you should do is to hardcode and obfuscate your public key. Having it as a file in the bundle makes you vulnerable to key substitution. (Basically, a cracker would replace the public key in your app by a different key they created using a private key they know, thus making their licenses valid instead of yours.)

Form Factors

While you may not realize it at first sight, this has become one of the most common methods in Mac shareware, thanks to the open-source framework AquaticPrime. AquaticPrime uses this technique behind the scenes, by embedding the signature in a plist file. AquaticPrime is a very easy way to use this. Unfortunately, if you decide to use AquaticPrime.framework in your app, it is very easy to replace the .framework file with a malicious one that will always claim your licenses are valid.

To date, as far as I know, there isn’t any HackuaticPrime.framework yet, but this might one day become a problem with AquaticPrime gaining popularity thanks to it’s extreme simplicity of implementation.

Update: Devon in the comments suggests implementing a hash check of the framework, which is a simple way of checking the framework’s integrity. Of course, there are still ways to get around it, but this makes it one step more difficult.

Another common form factor for Asymmetrical Cryptographic Keys is custom URL schemes. That’s actually a very clever and convenient way of doing it. To register, the users get to simple click on a link which looks like this: (All the user sees is a nice “Click here to register” link)


Another clever, but controversial form factor is Agile Web Solution’s 1Password License “Cards”.

And of course, if you find a way to make short base32 signatures (I hear DSA makes short signatures), you can even use longer Serial Numbers.


Sample Code

The code used in this article can be downloaded here.
As always, licensed under MIT license. If you do use it, mention it in the About Box or readme.txt.

Part One: Serial Numbers
The next part will be coming soon.

This entry was posted on Sunday, April 6th, 2008 at 12:13 am and is filed under Articles, Business, Cocoa, English, Hacking, Programming. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
Add your thoughts!
Devon thinks aloud
April 6th, 2008 at 3:36 pm

Just a typo:
“You then verify that the signature is valid using the private key in your app.” Should be public key not private key embedded in your shipping app.

I think you could improve the security of the Aquatic Prime framework by implementing a hash check in your application. Perform a hash of the whole framework with your favourite hash like SHA1 (MD5 is not secure enough). Embed this hash in your application and obfuscate it if you want so patching the binary is harder. When your app launches it checks the hash of the included framework against it’s own hash and would not work if someone tried to replace the framework.

I’m sure people might still find a way around that but it would be harder than just replacing a framework.

kenneth shrieks
April 6th, 2008 at 4:04 pm

Devon, thanks, this was indeed a horrible typo… You’re right, it is the public key that should be in the application!

And indeed, checking the framework against a hash is a very good idea, and every AquaticPrime app should do that.

David M mouthes
May 1st, 2008 at 6:08 am

You’ve got me hooked. Where’s part three? I’m going to be needing to implement something pretty soon. Thanks

kenneth whispers
May 1st, 2008 at 2:35 pm

David, this blog is pretty much on pause at the moment, along with everything else I do except support, right now… Main computer blown up by the morons at Eskom, waiting for it to come back for repairs…

Ken affirms
May 15th, 2008 at 5:39 pm

Hi Kenneth:
I found this very useful. Thanks for sharing!
Sorry to hear about your computer; hope it’s back soon. -Ken

Dharmender Singh spews
August 25th, 2009 at 1:33 pm

Thank you so much Kenneth for sharing code, this helps me a lot.

-Dharmender Singh

September 21st, 2009 at 2:03 pm

[…] Registration Schemes: Asymmetrical Cryptography | (tags: cocoa registration cryptography serial-numbering) Share/Save […]

Have something to say?