Encrypt SQLite Database File on iPhone OS

Any SQLite database on an iPhone is just a file associated with the application. For someone, itโ€™s quite simple to extract this file and request it.

What are your suggestions for encrypting a file or data stored in a database.

Edit: An application is a game that will be played against other users. Information about the relative strengths and weaknesses of users will be stored in the database. I donโ€™t want the user to be able to break the phone in prison to his reputation / power, etc., then win a tournament / league, etc. (NB: Trying to be vague as the idea is under the NDA).

I do not need military encryption, I just do not want to store things in plain text.

Edit 2: A little more clarification, my main goals are

  • Make non-standard hack sensitive data.
  • A simple way to find out if the data has been changed (some checksum)
+20
ios sqlite iphone encryption checksum
May 30 '09 at 13:39
source share
8 answers

You cannot trust the client, the period. If your stand-alone application can decrypt it, then they are. Either put the data on the server, or donโ€™t worry, since the number of people who really hack it to improve statistics will be insignificant, and in any case they will probably be rewarded for it!

Put the row in the database saying "please don't be fooled."

+18
Jun 02 '09 at 22:13
source share

There are at least two simple approaches (both free) that avoid encrypting values โ€‹โ€‹or databases in memory:

# 1 - ipa crack detection

Avoid the technical (and legal) hassle of encrypting the database and / or content and simply determine if the application is pirated and disables aspects of the network / rating / ranking of the game. See below for more details:

http://thwart-ipa-cracks.blogspot.com/2008/11/detection.html

# 2 - data integrity check

Alternatively, store the HMAC / salted hash of the important columns in each row while saving your data (and in your initial sqlite db). When loading each line, check the data by HMAC / hash, and if the check does not work accordingly.

None of the approaches will force you to fill out the encryption export forms required by the Apple / US government.

Grade Points

Do not forget that you will need to do something similar for actual applications in order to protect against values โ€‹โ€‹coming from something other than your application. You can see the implementation of this in the cocos2d-iphone and cocoslive structures at http://code.google.com/p/cocos2d-iphone/ and http://code.google.com/p/cocoslive/

Reply to comments

There is no solution that will 100% prevent data falsification. If this is a requirement, the client should only be viewed, and all state and logic should be calculated on a trusted server. Depending on the application on the client, additional anti-cheat mechanisms will be required.

There are many books on developing multiplayer games that discuss these issues.

Having a hash with a known secret in the code is probably a reasonable approach (at least when considering the type of applications that usually exist in the App Store).

+12
Jun 02 '09 at 5:34
source share

As Kendall said, including the key on the device, they are mostly asked to crack. However, there are people who have reasons for obfuscating data using a key on the device. If you decide to do this, you can use SQLCipher for your implementation. This is a SQLite assembly that provides transparent encryption at the page level of the entire database. There's a tutorial on Mobile Orchard for use in iPhone apps.

+11
Jun 29 '09 at 14:21
source share

How much do you think your regular user will do? I assume that you go through the application store, which means that everything is signed / encrypted before moving to the user device. They will need to jailbreak their device in order to access your database.

What data do you store for encryption? If it contains passwords entered by the user, then you do not need to encrypt them; the user will not need to know his password. If this is common BLOB data that you only want the user to access through the application, it could be as simple as storing an encrypted blob using the security API .

If this is the entire database that you want to protect, then you still want to use the security api, but instead, instead of all this, decrypt the file before opening it. The problem here is that if the application closes without cleaning, you still have a decrypted file.

You might want to look at resident databases or temporary databases, which you can create either with the db template or with a hard-coded schema in the program (look at the documentation for sqlite3_open ). Data can be decrypted, inserted into a temporary database, and then decrypted databases are deleted. Do this in the opposite direction when closing the connection.

Edit

You can prepare your own encryption scheme. I am sure that with a very simple XOR-ing security system, the data with the value stored in the application stores the hash in another place to make sure that it does not change, or something like that.

+5
May 30, '09 at 15:08
source share

SQLCipher:

Based on my experience, SQLCipher is the best option for database encryption.

Once the key ("PRAGMA key") is installed, SQLCipher will automatically encrypt all data in the database! Please note: if you do not install the key, SQLCipher will work identically to the standard SQLite database.

A call to sqlite3_key or "PRAGMA key" should be performed as the first operation after opening the database. In most cases, SQLCipher uses PBKDF2, the salted and iterated key output function, to get the encryption key. Alternatively, an application can tell SQLCipher to use a specific binary key in blob notation (note that SQLCipher requires exactly 256 bits of key material), i.e.

enter image description here

Link:

http://sqlcipher.net/ios-tutorial 

I hope someone saves time learning this

+3
Jun 13 '14 at 8:49
source share

Ignoring the problems of philosophy and export, I would suggest that you would be better off encrypting the data in the table directly.

You need to obfuscate the decryption key in your code. As a rule, this means breaking them into pieces and encoding strings in hexadecimal form and using functions to assemble key fragments.

For the algorithm, I would use a robust implementation of AES for any language that you use. Maybe this is for C #:

http://msdn.microsoft.com/en-us/magazine/cc164055.aspx

Finally, you need to know the limitations of this approach. Namely, the decryption key is a weak link; it will be available in memory at run time in clear text. (At a minimum) It should be so that you can use it. Implementing your encryption scheme is another weakness - there are any flaws and flaws in your code. As several others have indicated that your client-server messages are also suspected.

You must remember that your executable can be viewed in a hex editor, in which clear-text strings will jump out of random garbage, which is your compiled code. And that many languages โ€‹โ€‹(e.g. C #, for example) can be compiled with write-back, and all that will be missing are comments.

Everything that is said, encrypting your data, will raise the bar for deception. How much depends on how careful you are? but even so a determined adversary will still break your encryption and deception. In addition, they are likely to write a tool that will simplify your popularity; At this point, you will be offered an arms race scenario.




Regarding the value of the checksum, you can calculate the checksum based on the sum of the values โ€‹โ€‹in the string, assuming that for this purpose you have enough numerical values โ€‹โ€‹in your database. Or, for a bunch of booleans, you can save them in the varbinary field and use the bitwise exclusive operator ^ to compare them - you should get 0s.

For example,

for numeric columns,

2 | 3 | 5 | 7 | with a checksum column | 17 |

for booleans,

0 | 1 | 0 | 1 | with a checksum column | 0101 |

If you do this, you can even add a summary line at the end that summarizes your checksums. Although this can be problematic if you are constantly adding new entries. You can also convert strings to your ANSI / UNICODE components and summarize them too.

Then, when you want to check the checksum, just make a selection as follows:

 Select * FROM OrigTable right outer join (select pk, (col1 + col2 + col3) as OnTheFlyChecksum, PreComputedChecksum from OrigTable) OT on OrigTable.pk = OT.pk where OT.OnTheFlyChecksum = OT.PreComputedChecksum 
+2
Jun 04 '09 at 15:08
source share

It seems to be easiest to sync all tournament results with all the iPhones in the tournament. You can do this during each game: before the game, if the databases of the two phones contradict each other, a warning is displayed.

If user A falsifies the result, if his game is with user B, this result will be distributed until B sees him with a warning that the data does not match his phone. Then he can go and beat to explain to A that his behavior is wrong, so it is in real life, if someone is cheating.

When you calculate the final results of the tournament, show a warning, names and throw out all the games with conflicting results. This takes away the incentive to cheat.

As already mentioned, encryption will not solve the problem, because you cannot trust the client. Even if your average person cannot use the disassembler, all that is required is one motivated person, and any encryption that you have will be violated.

+1
Jun 08 '09 at 13:27
source share

However, if on a Windows platform you can also choose SQLiteEncrypt to suit your needs. SQLiteEncrypt extends sqlite encryption support, but you can treat this as the original sqlite3 c library.

-5
Jan 07 '10 at 13:16
source share



All Articles