Can anyone help me to make the contents of my Documents directory secure?
Use:
- (BOOL)writeToFile:(NSString *)path options:(NSDataWritingOptions)mask error:(NSError **)errorPtr
with one of the file protection options:
NSDataWritingFileProtectionComplete (iOS 4.0)
NSDataWritingFileProtectionCompleteUnlessOpen (iOS 5.0)
NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication (iOS 5.0)
See: Apple Documentation
NSDataWritingFileProtectionComplete
In this case, the file is stored in an encrypted
format and may be read from or written to only while the device is
unlocked. At all other times, attempts to read and write the file
result in failure.
Note: Doing your own encryption raises the problem of key storage and the best answer there is to use the Keychain. Key handling is the biggest problem and the NSData methods handle that.
We cannot secure the file in documents directory. We can store the file in temp folder of the device. This cannot be accessed by anyone
use encryption and decryption for making and reading those files on iphone take an idea from here http://iphonedevelopment.blogspot.com/2009/02/strong-encryption-for-cocoa-cocoa-touch.html
Alan Quatermain provides a toolkit that has some helpful wrappers around the cryptography libraries to make encryption/decryption really straightforward.
Here's the link:
AlanQuatermain / aqtoolkit
Whatever you do, just make sure that you don't store the document on the device unencrypted, even for a short time. Always store it encrypted. Perform any encryption operation in memory.
Be sure that for any file operations you do not cache. So for example, any downloading, etc. you want to make sure that no data is written temporarily to disk.
Finally, for your encrypted documents, do not store the key on the device in any format. Do not store it on the keychain either.
Try to encrypt content. take a look Strong Encryption for Cocoa / Cocoa Touch
Related
Health related data for a user is a privacy thing and its need to be very secure i.e. it needs to be stored in secure place. For example, while I was watching Apple's official video on Finger print unlock, they told that finger print data is stored at place where it is impossible to hack. So, for a curiosity, I have a question in mind that where these data are securely stored?
I have had a look at this link from Apple Documentation but could not found the information on it. One thing I have figured out is that data are encrypted and stored but where?
Does anyone has idea on the same?
Apple describes the security attributes of various iOS features in this document. To quote:
This data is stored in Data Protection class Protected Unless Open.
Access to the data is relinquished 10 minutes after device locks, and
data becomes accessible the next time user enters their passcode or
uses Touch ID or Face ID to unlock the device.
Read the "Encryption and Data Protection" section of the document to learn more about Data Protection. Any app can use the "Protected Unless Open" data protection class for its persistent data.
As you already know, NSUserDefaults is simple and effective for saving small, simple bits of data, like NSNumbers or NSStrings, to your device’s file system. But this data is in no way stored securely as hackers can access it pretty easily from the device.
You have figured out that sensitive data are encrypted. But you need to find the answer where it need to be stored. The Answer is:
Keychain Services:Apple has provided the Keychain Services API to deal with this problem and help developers build apps that safely handle passwords and other sensitive information.
Now the question might rase why?? and the answer is:
Keychain is great because data encryption automatically is taken care of before it is stored in the file system so there is no need to waste time building encryption algorithms.
You can go through this link for better explanation.
https://developer.apple.com/documentation/security/keychain_services
How can I encrypt file in the iOS app's bundle to prevent data from copy? I can suggest to encode/decode it by simple rules. But it will take too much time to encode on every app start and it's not safe enough.
P.S. We should not cause export restrictions. So encrypting algorithm must be not strong.
The App Bundle can not be changed by the app so that option is not available.
If it is something that is included at build time you can encrypt it prior to building the app and decode it in the app when you need it.
The problem is that the encryption key must be provided to the app in some manner. Just including the key in the app code is not secure but may meet your needs. Providing the key from a web site with authentication might work for your needs.
You need to evaluate the level of security you require, who you are protecting against and how much effort/money they are willing to expend to get your data.
Note: encryption with Common Crypto is very fast. On an iPhone6 I benchmarked the speed as 1MB in 10.8 mSec or 92MB/sec.
Just use double encoding if data isn't too sensitive. For example, utf8 + base64 with several char replacements to hide that it's base64.
There are some files that I want to download and store in the sandbox. However, they must stay secure (i.e. encrypted) all the time. Now, I can encrypt them while downloading to the Documents itself. But when the files need to be consumed I have to decrypt them before that. The question is where to put these decrypted files?
tmp - Looks like a good place to keep it, but then what if the contents are deleted when the app has been kept minimised for days.
Documents - Keeping the decrypted file here in a separate place may not be a very good idea. It is not automatically cleaned up when the app is relaunched and if the device runs out of battery while the app is still running, these decrypted files will get exposed.
So the moot question is what the best way to ensure Documents directory's data security.
One useful aspect of UNIX-based systems is that you can create/open a file and then immeditely delete the file. The file won't be accessible from outside the app, however the app will be able to read/write data to the file and the file will not actually be deleted until the file handle is closed.
This means you can create/open the decrypted file anywhere within the app's accessible file structure.
While I haven't tested this under iOS, I think there is a good chance it will work.
I would keep the encrypted files in the Documents directory, encrypted with the NSData NSDataWritingFileProtectionComplete option.
If you feel the need to encrypt the files yourself and then decrypt only as needed save the decrypted files in the Documents directory, encrypted with the NSData NSDataWritingFileProtectionComplete. Add the "do not back up" extended attribute to the file. On app launch/wake, etc, based on the police overwrite files that are no longer needed and delete. Use AES, CBC mode with a random iv, random key and keep the key in the Keychain.
An option to open as a stream and decrypt on the fly into a buffer, if this works for your app.
But the catch is I really don't understand you full use-case. Best practice: Hire an iOS security domain expert to advise and vet your solution, I do. Is the security worth that price, a valid question.
In explanation to my comments: I wrote an application to recover images from a corrupted HD, not all that hard.
I am busy writing a commercial electronic words-dictionary type of app for iPhone and iPad iOS7. The value of the app is really in the database that I worked many years on, and not so much the app itself. The database is very large (195mb on a windows computer before converted to something like SQLLite) and I and would like to know what is the best way to protect the data in it so the app can read it but other people cannot read/get to it. It seems most mobile developers use SQLLite, but the data can easily be read with a normal hex editor on it.
From this forum and others I gathered that SQLCipher is a good tool. My problem is that it SEEMS that SQLCipher encrypts the database, and then decrypts it when it needs to be read in a temporary file and then encrypt it again afterwards. If this is the case, I have two problems.
The database is very large and to decrypt it every time and encrypt again is going to make the app very slow.
What stops a hacker from reading/copy the decrypted (temp) file when it's available even for a short time?
Do I understand SQLCipher's working correctly, if so, is there any other tools/methods to encrypt/protect a database so that the program can still read it with SQL Queries without making the data so easily available in any way, or any other suggestions you might have?
Thank you
According to this page: http://sqlcipher.net/design they don't decrypt your database as a whole, so the answer to your question #1 is no. They claim about 5-15% overhead to the standard SQLite performance.
As for #2 - SQLCipher will decrypt database in pages, so theoretically - somebody can get access to that page in memory in decrypted way. However this would be true for any encryption method you use. Just think about it - even if you decrypt full database, your application would need to display/access some data from it, somehow at some point. And at this point data must be decrypted. The only question here - how much of the data will be decrypted at given moment.
The other alternative you have is to try to implement ecnryption/decryption yourself using standard SQLite and standard ecnryption library. You can for example encrypt each row (or even fields with sensitive data) individually and decrypt them when needed - but then again, at certain moment this particular row will be in the memory decrypted and visible to hacker.
I've browsed through about 2 dozen articles here and elsewhere looking for an answer. No one seems to have addressed this problem --
We have an application that has fairly large database (on the order of 5MB). The application needs the DB when working offline. The DB can be recreated by downloading from our server when online.
We can't use Core Data instead of our own DB because the data must be encrypted to meet government privacy standards.
The app cannot function offline without this database, so it can't go into Library/Caches.
We can place the data in Documents and mark it "do not backup" for iOS 5, but this doesn't work for iOS 4 since that attribute is not recognized.
So what can we do with the database in iOS 4?
Just off the top of my head.
I guess you could subclass NSManagedObject so that it encrypts any data that gets saved to Core Data and decrypts it when you read it. There will be a lot of overhead on the CPU though. There might be someway to optimize it.
Check this out: AES Encryption for an NSString on the iPhone
Put it in (sandbox)/Library/Application Support. Here is how Apple describes the Application Support folder:
Resource and data files that your app creates and manages for the user. You might use this directory to store app state information, computed or downloaded data, or even user created data that you manage on behalf of the user.
Quoted from Apple's File System Programming Guide for iOS.