A better way to handle full version unlock?

I currently have a few games available that one can download for free to try and then (hopefully) pay 99 cents to unlock the full version.  My methodology for handling this is simple - I have a settings.json file in my game that sets a full game flag to true after an in-app purchase.

I’m finding that this leads to what seems like a very easy hack to get the full version for nothing.  Does anyone have a better method for handling this that would make this more secure?

Any advice is appreciated.

GlitchGames has a nice little data storage module which supports cryptographically encoded storage: https://github.com/GlitchGames/GGData.

I just wrote up a short article with a demonstration of how I use GGData (in my own module) to handle IAP and other secured settings:

http://roaminggamer.com/2014/06/15/secure-data-storage-for-corona-sdk/

That’s what I’m talking about.  So helpful.  Thanks very much.

Thank you so much for taking the time and going through how you use GGData. Have you looked at the new Crypt library from Graham Ranson? Any plans to move towards that library instead of GGData?

ksan, looking at the crypt library, it looks like it functions similarly to the utilities library (where you save your variable as a able and then load that table in using the library).  Am I reading this properly or completely off base?

Yes. I think thats how you use Crypt. I use GGData in this way as well and works well. I still didn’t have the time to figure out if Crypt changes anything. GGData works great as it is. 

Thanks to you both.  I am totally going down the GGData path.  Looks good to me.

Thanks again!

Just curious. As soon as you use encryption, doesn’t Apple ask a bunch of questions and require an ERN authorization to be submitted?

One thing to note with GGData is that it doesn’t store data in an encrypted format. The data is fully readable in JSON format.

However GGData does add a hash to each entry that’s used to detect tampering.

I also noticed that variables that are set to false are reported as corrupt by box:verifyIntegrity(). When they’re true it’s OK.

this is really cool, and timely for me too :slight_smile: , thanks.

if you use strings for all the variables you can use “false” and “true” no problem.

what would happen if a user shared their ‘box’ with someone else? ie bought the full version , then shared it with others including the ‘box’ ? are the hashes unique per device?  i suppose you could store the device id but that’s a little controversial on android.

cheers!

Yeah.  I’m a little confused by this “adds a hash to each entry” thing.  What does that mean?

And, if it is not altering a true variable in any way, then would setting like “full game = true” mean that a user could still do what I’m trying to avoid them being able to do (alter a file to get the full version).

Sorry for the further questions.  I just want to find the best solution for the easy full game hacks. 

I’m a little confused by this “adds a hash to each entry” thing.  What does that mean?

GGData stores your values in clear JSON text, but it also adds an extra table to the JSON data which includes a hash for each entry of your settings. If you look at the data file that GGData produces you’ll see what I mean. (In the Corona Simulator choose File->Show Project Sandbox, and open the file).

Even though the JSON data is clear text, users can’t tamper with the data as the hash is protecting the original data. What will happen if a user tries to alter the data is that the value that’s been tampered with will be reset to its default value.

Sharing a box will be possible if you give the same key to GGData for each device. If you come up with a way to specify a different key for GGData for each device you’ll be OK.

if you use strings for all the variables you can use “false” and “true” no problem.

Beware that “false” isn’t the same thing (logically) as false.

right , but it’ll work for what i need.

so given that deviceID is a little contentious on android (permissions wise)  do you have any suggestions for unique key generation?

thanks for you help with this!

Sorry. It’s tricky to get anything unique within Corona without going native, and even then I don’t know what I’d choose.

Personally I’ve stopped worrying about pirates. It takes too much time and effort away from my development. The thing is, no matter how difficult you make it, there’s always somebody who finds a way around it. 

GlitchGames has a nice little data storage module which supports cryptographically encoded storage: https://github.com/GlitchGames/GGData.

I just wrote up a short article with a demonstration of how I use GGData (in my own module) to handle IAP and other secured settings:

http://roaminggamer.com/2014/06/15/secure-data-storage-for-corona-sdk/

That’s what I’m talking about.  So helpful.  Thanks very much.

Thank you so much for taking the time and going through how you use GGData. Have you looked at the new Crypt library from Graham Ranson? Any plans to move towards that library instead of GGData?

ksan, looking at the crypt library, it looks like it functions similarly to the utilities library (where you save your variable as a able and then load that table in using the library).  Am I reading this properly or completely off base?

Yes. I think thats how you use Crypt. I use GGData in this way as well and works well. I still didn’t have the time to figure out if Crypt changes anything. GGData works great as it is.