11-21-2009 11:07 PM
We use the application web loader to distribute our app.
If the customer have paid for the application we want to pre-register it so that he does not need to have to enter the license code himself. Hence, we need some method of automatically getting the license code onto the customers device at the time of loading.
The obvious would be to have some code on the webserver modify the cod and insert the license string. In order to do that, we need to know the .cod format, but after googling the web we've found some good info, but is is all patches and fixes and not officially supported by RIM.
What is the best method (or is there even an officially supported method?) to include a unique license code at the time of download?
Solved! Go to Solution.
11-22-2009 09:02 AM
I don't know about your web application loader but if you use App World to purchase and install the app you can have the app query App World for the license at run time.
Besides it's not exactly a good idea to try and modify the *.cod file because, a you found out already, it is not officially supported by RIM. Also from what I remember reading about *.cod files they use a whole lot of offsets so if you tried to insert the license key you could mess up the offsets and thus cause verification errors when you try to install the app.
If you really want/need to install the license key into the *.cod then you might want to get in contact with RIM to see if they can come up with a official solution.
11-22-2009 12:40 PM
1. You could build your original/template COD file with a known value for the license string/byte array. You can then locate and replace this known value with the actual value for the customer. Note that, if the module is signed, this will invalidate the signatures, meaning you'll need to automatically re-sign it.
2. Another solution is to append the license key as a "signature" of the module. Signatures, by definition, are not covered by module signatures. You can then use the CodeModuleManager API to obtain the "signature" (it's just a byte array) from your BlackBerry code. For example, append 01 00 84 00 41 42 43 44 followed by 128 bytes containing your license key. The signer ID in this particular example is "ABCD" (bytes 4-7), but it can be anything. The length of the signature (+4) is in bytes 2-3 (little-endian). I've never tried using a length that is not 128 bytes, which is the length for standard code signatures.
11-22-2009 01:26 PM
That is very interesting, I didn't know about that.
11-22-2009 07:39 PM
That IS interesting, but if it's a static license key you'd have just created a working .cod that can be copied and distributed by pirates. If it's a dynamic license it's still an all-too-obvious place for the key and would make it easier to make a pirate keygen to patch your .cod.
If you store the license key in the persistent store, it should at least be a bit harder to find -- wouldn't someone have to dig through your .cod to find the place where you calculate the location you're using in the store? or else find all locations used in the store by your application -- either of those seem harder than just doing a diff on the modified cod versus the original.
My two cents
11-23-2009 04:53 AM - edited 11-23-2009 04:54 AM
I agree with some points raised by mlamagra. I assume the author of this thread is aware of the various issues caused by the license key being distributed inside the module. The question in this thread is how to best achieve that.
P.S. As to making it harder to redistribute a particular instance of the module, the license key could easily depend on the BlackBerry's PIN. For best results the license key should contain an RSA/DSA/ECDSA signature that can only be generated by the manufacturer of the software. Now the attacker would have two obvious choices: replace the public key with that of their own, or modifying the bytecode of the module in order to disable the check in the first place -- this can be done regardless of the protection scheme used anyway. PersistentStore is not much better at storing the license information, because it's fairly easy to find out the GUID under which the app stores something.
11-23-2009 06:14 AM
how do ytou find the GUID, just run it in the emulator and look at the stack trace/ parameters?
It is possible to use different code with isSimulator() to at least make it more confusing without the source/debug info.
11-23-2009 06:30 AM
I'm sorry, I responded to the followup but didn't fully read the first post. I suggest including a license file in the package without modifying the .cod, and then on 1st run the app reads the license from the file, stashes it however you deem most secure, and then modifies some critical bytes of the license file and then deletes it. If it's undeleted it will be useless, and chances are the user didn't think to make a copy before eagerly running their app for the first time.
Then just have the customer give you their PIN, you generate the license file using an in-house keygen, and send them the app with their license attached -- no need to modify the .cod, and if someone else does get ahold of the license file, it will only work on the intended specific device. If you use RPN, encrypt it to make analysis more difficult.
Maybe you could also have the app contact your website to get the license at installation, and completely dispense with distributing a license as part of the distribution package.
As for how to stash the license securely on the phone after it's read from the license file or obtained from your website -- in my own apps I realize that anyone can find out where I'm stashing it easily enough, so I just try to focus on preventing them from cracking it once they've found it or cracking my program code.
One big thing to avoid is, when you discover the license is invalid, don't pop up a message from code easily associated with the code that determines the license's validity. Otherwise a hacker could just run your app in a simulator and wait for the "license invalid" message to pop up, break the program, and trace back to where you checked for valid license, replace your "if code == rightcode" with "if code != rightcode" and your app is cracked ;-) Instead, use some roundabout method of getting another thread to pop up a message at a random time after the invalid license is discovered. And check for license validity at multiple points in the program, some 'down the road' not just at startup.
11-23-2009 08:21 AM
Thanks for all good sugestions.
In our case, we use a dyamic key based on the PIN of the phone and we do use encryption, so it does not really matter if someone finds the code storage location.
Our idea was to use a dummy string and replace that at run time with the real string, but as klyubin points out that invalidates the signing. We would like to avoid running the signing tool in the background on the server and therefore turned to you great supporters on this site for help.
I pressume that mlmagra's idea of including a license file is also failing on the signature requirement. Correct?
Letting the app itself find the license key over the internet is a clean solution, but this app does not require internet access and we would then code that only for this purpose. Seems a little bit overkill.
Thanks for the input!