Protecting in app purchases against piracy

So in your app once the user has purchased something, you have to save some flag in your application, if I’m right. I would probably do this in the form of a file in the documents directory, saying whether or not they had purchased an item. But, if they just browse the iPhone filesystem (which is fairly easy to do, especially if it’s jailbroken), they could find the file, what it has, and post that on the internet for everyone to see. Then all they would have to do is create that file. So, would it work to hash (with MD5, SHA or similar) the device id with some ‘salt’ or string, and store that in the file? Then every time they try to access paid content, generate the hash for their UUID + the hard-coded salt, and check the hashes? If they match, a-ok. If they don’t…
So my question is would this work? Or is this already somehow taken care of for you? My other question is would the hashing algorithm require you to do all that encryption export stuff? The agreement says “… uses or supports any data encryption or cryptographic functionality…”? I’m new to this, so any help is appreciated. Thanks for reading through the end of my ramblings… [import]uid: 8782 topic_id: 5792 reply_id: 305792[/import]

I am pretty new to this too and am very interested in the answer to your question about requiring encryption application with Apple.

I was thinking about going a slightly different direction then you and hashing the saved file itself with a hard coded key and the device ID. Then save that hash in a different file. This way if either file gets tampered with or moved to a different device, reset internally. [import]uid: 9187 topic_id: 5792 reply_id: 19883[/import]

Is piracy actually that big of a deal for IPhone games? [import]uid: 11219 topic_id: 5792 reply_id: 21482[/import]

Yeah, I thought about this and decided I’m not going to worry about it “now”.

I’ve got some decent flurry analytics logging in place… I should have a good idea (in terms of numbers) of who’s using what and I should be able to compare that to who’s paid for what (total numbers) to see how bad it was.

After that, it’s a matter of deciding if “doing something about it” makes sense. That is… are people who steal likely to be buyers? Probably not. So is the time spent worth just stopping people from stealing? And again, probably not.

But … this is my initial impression after thinking on it. I’m storing and dealing with the purchases in an sqlite db, so there’s a little more to do than just dropping a file in a directory. All the same, my method still makes it generally easy to “hack” past the in-app purchase on a jailbroken device.

If I change my thinking on this, I’ll update the thread. *chuckle* [import]uid: 13859 topic_id: 5792 reply_id: 21596[/import]

Best thing to do, IMO, is to find a way to detect if the app has been cracked and keep track of how many people are using a pirated version… If the number is low, no need to waste time studying protection measures. [import]uid: 9158 topic_id: 5792 reply_id: 21603[/import]

This is an interesting post. I think in app purchases checks if the user has purchased the items as soon as it starts. “store.init()”

I am not clear how this then interacts with our apps to block or allow what was purchased.

Can anyone explain this a little further?
[import]uid: 8192 topic_id: 5792 reply_id: 24619[/import]

Among many other neat features, I am incorporating In-App Purchases in my first Corona-based game.

Since I’m using the JSON module to read/write my tables and it’s resulting files are saved in plain text, one of the things I was concerned about as well was piracy.

By implementing the crypto module, I am able to add a “CRC” value in my table to make sure that everything else in the table has not been modified, or else it would invalidate the particular protected contents of the table.

When a legitimate purchases is made, the value will be written into the table, and a new CRC will be computed and added to the table.

When the program launches, it will read the table along with the CRC, and if the file in the CRC doesn’t match the CRC immediately generated with the values in the table, the data is considered modified.

One thing I would mention is being wary of creating a hash against the device ID. If a person happens to change their iOS device, and it happens often, either switching from a broken iPhone or upgrading to an iPad, and it restores the data, they would be mighty upset if some of their game progress was nixed in the process. For that instance, I base the key against a value stored in the game, plus a timestamp, which is also stored in the table. So basically, you’re only storing part of the “key” in the file, while the other half of the key remains hidden in your game.

I hope that helps, I’ll post some code as soon as I have some free time - I’m in crunch mode, trying to finish the game! [import]uid: 6084 topic_id: 5792 reply_id: 24651[/import]

@BeyondtheTech.

Thanks so much for your input. I think I understand what your are saying. Any code would make it perfectly clear.

I am implementing a remove ads feature for 99c. I am unclear if the in APP would check each time it launces if removeads was purchased. Or if it was purchased someone could pass the ipa to someone else and it would not have ads.

[import]uid: 8192 topic_id: 5792 reply_id: 24758[/import]

BeyondtheTech - I have to disagree with you on the device ID hash. But only in regards to purchased items. Using your method would essentially allow one user to purchase, then pass their save file around to others.

I’m not saying I believe this is a huge threat, but if you are trying to be completely secure, you need to hash against something unique to each user.

Using the device ID fits the bill for revenue generating saves because a legitimately purchased item is linked to your Apple account and can easily be restored in the case of a reformat or device swap.

Maybe a hybrid approach would work best. Locking down revenue generating data in its own save file linked to the device. Then having other information like high scores or level progress saved in a less secure but more mobile file. [import]uid: 9187 topic_id: 5792 reply_id: 25038[/import]

Personally, I don’t worry too much about piracy because I figure at least it’s more exposure for your app, from people who probably wouldn’t buy it anyway. Some pirates even buy a game if they like it (very few, I’m sure).

Anyway, what I would do if I were to “battle” piracy would be to offer my game free… with an in-app purchase to upgrade to the full version directly from within the app. I’m sure there’s a way to hack it still, but it sure is a lot more difficult to pirate that than a paid app. [import]uid: 7849 topic_id: 5792 reply_id: 29590[/import]

You misunderstood the question. Hacking in-app purchases was precisely what he was wondering about.

I think in app purchases checks if the user has purchased the items as soon as it starts. “store.init()”

That’s probably true but not going to help you if the user launches the game without connectivity. Imagine firing up your iPhone on the plane; the player will rightly expect access to the goodies they purchased. You should be storing the data locally but with online verification when possible.

If a person happens to change their iOS device, and it happens often, either switching from a broken iPhone or upgrading to an iPad, and it restores the data, they would be mighty upset if some of their game progress was nixed in the process.

How do you preserve data across devices? I’ve been wondering if there’s a way to save somebody’s settings from the lite version after they upgrade to the paid version.


This entire discussion is making me reconsider my approach to storing scores, which is a similar problem. If it is easy for people to browse the file system on a jailbroken iPhone (I did not know that) then that would be a serious cheating risk. I guess I should come up with a scheme to make sure the data hasn’t been tampered with before using it. hm…

ADDITION: oh wait I know, I could just use the encryption technique I described here:
http://developer.anscamobile.com/forum/2011/01/24/can-someone-explain-me-how-use-encryption-md5

Basically, hash the data with a password when saving it, and then re-hash the data with the same password when loading it. If the saved hash matches the new hash then the data wasn’t tampered with. The only information in that sequence that needs to be secret is the password, and that is in the app not in the saved data.

Thanks for asking this question robert, now I can solve a problem I didn’t even realize I had. Unfortunately this doesn’t solve your problem, because you need to have a password that is both secret and unique to every player.

ADDITION2: oh wait I just noticed in your original post you came up with a solution and simply wanted us to confirm whether or not that’ll work:
generate the hash for their UUID + the hard-coded salt, and check the hashes? If they match, a-ok. If they don’

Yeah that’ll do it. The UUID is unique to every device, and then combining it with your hard-coded salt will make it secret. At that point you have a secret password that is unique to every device, what you need for the hash verification technique. [import]uid: 12108 topic_id: 5792 reply_id: 30222[/import]

Just an addition to this thread, for my new game thats just gone into the App Store (‘Thumb Tap’, check it out!), I used the UUID of the device with hard coded keys inserted into them to generate a unique hash code for each in app purchase item. This code is saved into the game’s config file when the in app purchase is made. Before the purchase has been made, the game’s config for the in app purchase item is blank (which the game interprets as locked/unpurchased).

Whenever the device loads my game again, it regenerates the code again internally and compares it to what is in the game’s config file. If they don’t match, then it means that the config has been copied from another device or tampered with, so my in app items are locked again and the config is blanked out.

Its also not a problem if the user loads up my game on a different device, they just go through the same in app purchase process again under their iTunes login (but aren’t charged this time) and the game unlocks my content again (kinda like a restore).

The only way I could see that this can be abused is if someone logs into their own iTunes account on a friend’s device (having previously legitimately purchased the in app items on their own device), then unlocks them for their friend. I haven’t worked out how to get around that one but I’d imagine it wouldn’t happen *too* often…

Oh and as for transferring save data between devices, I’m not rich enough to run my own backend database to allow for this, so if you go to a new device, sorry but you start again progress wise… [import]uid: 9428 topic_id: 5792 reply_id: 30568[/import]

It’ll definitely be interesting to see how the anti-piracy suggestions work–anyone who tests it out, please let us know!

Also keep in mind, I don’t think piracy ever killed an app.

Look at Angry Birds. Due to it’s extremely high position in the App Store (for multiple platforms even), it’s probably one of the most pirated apps out there–and as far as we know, the developers are still making a boatload of money with it.

Plus, piracy can’t be all bad… exposure is one of the main ingredients to making your app a success :slight_smile:

My single highest performing game is Tilt Monster (formerly known as Doodle Dash)… it’s momentum started when it was featured on OpenFeint’s FREE Game of the Day. That means tons of people got it for free… but all the exposure it got from the free downloads, people spreading the word, etc. made all the difference when the promotion was over.

Great discussion though–very, very good ideas on how to protect your apps from in-app purchase piracy. But don’t get too discouraged if you can’t find a fail-proof method. Personally, I don’t think it’s that big of a deal–but that’s just my opinion.

I’m pretty sure that there’s a relatively small number of people who actually know how to hack a game to get in-app purchase item for free. And the amount of people who do know how to do that is probably a very small minority, and even more of a minority when it comes to that same group of people finding *your* app.

Just some things to think about… [import]uid: 52430 topic_id: 5792 reply_id: 32213[/import]

Get used to rate of 90 to 95 percent pirated apps. That seems to be pretty normal these days. [import]uid: 5712 topic_id: 5792 reply_id: 32222[/import]

Even so I don’t think it hurts to a least try to protect your investments. My new game is by no means popular but from 2700 dowloads i am yet to see any pirated inapp purchases via submitted game scores etc. Of course i dont see any unauthorised download stats and no doubt a lot of JB phone users dont use openfeint so I don’t have the complete view, but I’m happy to at least make it a bit harder than editing a config file with a text editor to unlock my content. Its’ pretty basic for IAP based games to use the hash code method so I reckon its still worthwhile. Just my 2 cents :slight_smile: [import]uid: 9428 topic_id: 5792 reply_id: 32226[/import]