Secure Data Save

I have tried saving my game stats such as saved score using the file demo and SQLite demo with success, but have concerns about security.

Both of these methods leave the data in plain readable/editable format within the apps sandbox. I have been able to edit the saved files and give myself a crazy high score with little effort.

Does anyone here currently use or know of a more secure method of saving game data? I was thinking about giving it simple encryption before saving but am not really sure if this is the best method or how to go about it.

Thanks! [import]uid: 9187 topic_id: 4224 reply_id: 304224[/import]

Anyone? Ansca?

Maybe I am worried about nothing. I am not really familiar with how easy it is to access these files on the phone its self. But any information or tips would be appreciated. [import]uid: 9187 topic_id: 4224 reply_id: 13264[/import]

You can have a look at the “crypto” lib (require(“crypto”)). And, encryption is probably the best thing you can do.

A “light” way is, instead of actually encrypting data, to generate a hash of that data.(crypto lib again) The data will still be readable and modifiable, but the hash value will tell you if someone hacked into your saved data. Just remember to generate a new hash every time you save the file.

If the hash doesn’t match at load time, then someone is trying to cheat and you can either reset back to some default or erase the file and start anew. (they actually tried to cheat…so who cares for the highscore! :stuck_out_tongue: )

BTW, it’s good to include such basic security since jailbroken phones can actually access your sandbox and modify files! [import]uid: 5750 topic_id: 4224 reply_id: 13737[/import]

erpy, thanks for the explanation. The Corona docs. are pretty vague and assume a knowledge of encryption that I don’t personally have. I also couldn’t find any Ansca or user-submitted examples utilizing encryption. Is there any chance you could post an example showing how to use the Corona encryption commands to “hash” a data file while saving it and then verifying it on reload?

I suspect it’s not terribly complicated, I just don’t understand the usage basics. Like, what to use for a key, or how to store the key so it’s secret, etc. My goal, like tempop, is to prevent a user from tampering with saved score and/or level data to cheat or otherwise alter game-play.

Thanks for any info. you can provide. [import]uid: 9422 topic_id: 4224 reply_id: 13810[/import]

@XenonBL

Hi, sure, here’s some sample code to begin with:

[lua]crypt = require(“crypto”)

function game:loadStatus()

------------------ HASH SECURITY - LOAD
local hpath = system.pathForFile(“hashFilename”,system.DocumentsDirectory)
local hfile = io.open(hpath)
local shash

local function okButt(event)
self:resetGame() – you’d eventually want to reset game after the alert
end

if not hfile then – hash file must be there, unless it’s “first launch”
native.showAlert(“Error”,“File not found! Press OK to continue.”,{“Ok”},okButt)
return
else
shash = hfile:read() – reads content of hash file…which is the hash string
hfile:close()
end

local fpath = system.pathForFile(“saveDataFilename”,system.DocumentsDirectory)
local cfile = io.open(fpath) – loads save data file

if not cfile then – data file must be there, unless it’s “first launch”
native.showAlert(“Error”,“File not found! Press OK to continue.”,{“Ok”},okButt)
return
else
local content = cfile:read("*a") – reads save data file - it’s a text file in this case
local hash = crypt.digest(crypt.md5,content) – generates md5 hash of the read data file

if hash == shash then – if the two hash strings are equal…
cfile:seek(“set”) – seek to the beginning of data file…so you can begin reading it normally
else – otherwise close the file. Someone cheated!
cfile:close()
native.showAlert(“Error”,“Someone tried to cheat! Press OK to continue”,{“Ok”},okButt)
return
end

– READ THE DATA FILE SAFELY AFTER THIS POINT
– …
end
end

function game:saveStatus()

------------------ HASH SECURITY - SAVE
local fpath = system.pathForFile(“saveDataFilename”,system.DocumentsDirectory)
local cfile = io.open(fpath)

– …
– SAVE ALL THE GAME DATA HERE
– …

cfile:close() – close the file first!

cfile = io.open(fpath) – reopen data file
local content = cfile:read("*a") – and read it all in a string

local hash = crypt.digest(crypt.md5,content) – generate a hash of the data string
cfile:close()

local hpath = system.pathForFile(“hashFilename”,system.DocumentsDirectory)
local hfile = io.open(hpath) – open the hash file

if not hfile then – if doesn’t exist, create it
hfile = io.open(fpath,“w”)
else
hfile:close() – otherwise open it in update mode - and overwrite it
hfile = io.open(fpath,“w+”)
end
hfile:write(hash) – save the hash string
hfile:close()
end[/lua]

It is actually quite easy. You can also easily make a couple of generic functions out of this.
Note that this is only for files the app saves/reads in the Temp or Documents directory…since Lua scripts cannot be modified as they’re compiled by the Ansca builder.

The only thing you need to take care of within this sample code is the “first launch” situation. It’s not uncommon to save a dummy “launched” file and then check for it later on.

I hope this helps. [import]uid: 5750 topic_id: 4224 reply_id: 13814[/import]

Does using the crypto libraries to generate a hash mean one has to answer yes when submitting an iOS app for approval? From what I understand, doing so makes the acceptance process significantly more difficult (and may limit worldwide availability). [import]uid: 1560 topic_id: 4224 reply_id: 13836[/import]

I don’t know if using crypto lib can slow down approval.

Usually they want to know whether you employ “strong encryption” systems, such as RSA and the like, since there are export restrictions in certain countries.

Not sure sha1, md5 etc. fall within this category. [import]uid: 5750 topic_id: 4224 reply_id: 13858[/import]

@erpy,

Many thanks for the code example! It does help me understand how to use encryption. [import]uid: 9422 topic_id: 4224 reply_id: 13859[/import]

this link says to answer no because md5 is not encryption
http://stackoverflow.com/questions/6296667/appstore-approval-and-md5 [import]uid: 89663 topic_id: 4224 reply_id: 102460[/import]

To go one step further, if you assume your cheater recognizes and MD5 hash when he sees one, you can instead use crypto.hmac to salt your hash with a private key:

[lua]local hash = crypto.hmac( crypto.md5, content, “aSecretPassword”)[/lua]

That way, even if a cheater changes their score *and* the hash, you can catch them. [import]uid: 44647 topic_id: 4224 reply_id: 102461[/import]