I'd appreciate that someone could make it clear some questions I have regarding Data Protection feature:
Is needed/recommended to enable Data Protection to encrypt and protect the SQLite files managed by Core Data? If so, what should I do to encrypt and protect such files?
I followed a tutorial for using Keychain and it said that complete level of Data Protection had to be enabled for the App ID in the Apple Member Center, so that I did. However, it said nothing about also enabling Data Protection in the Xcode's project, so I didn't. It seems that I can access Keychain in my iOS app without problem, but this looks weird... should I also enable Data Protection in the target's settings?
Thanks so much
It depends what you're storing there and thus what is at risk if someone gains access to it. In most cases you don't need to encrypt the data in the DB specifically as someone will use a device lock to secure the device and any specific data that you want to make secure should be stored in the keychain. This is usually the user identifying data and account authentication tokens.
If someone gets access to a device that is unlocked (pin code / touch ID has been cleared or authenticated) then they can do pretty much whatever they want with the device (keychain and automatically encrypted data) and you can't stop them (at best you can slow them down).
Apple does mention you can limit access to Keychain data if someone tries to add their fingerprint after-the-fact. More info in the Keychain section of https://www.apple.com/business/docs/iOS_Security_Guide.pdf
The only thing you can do really is to explicitly encrypt the data which requires it using a key that is explicitly entered by the user each time you need to encrypt / decrypt. That key could be stored in memory temporarily, but you can never write it to disk. In this way the user has to enter the key to use the data and the key can only come from the user.
Related
I am saving an important key in the iOS keychain. Everything seems to be working okay right now. There has only been only one issue. The keychain data is still alive after you delete the App. Which I was able to resolve by checking if the App has just been installed and deleting the data in the keychain. However, I want to be sure if there isn't any more issues or pitfalls I should be looking for.
The Apple keychain uses 256 bit AES encryption to secure data. It is ostensibly the mechanism that Apple uses internally to store private data such as your passwords as well. Other than your comment about the data being persisted after you delete your app (which is a feature not a bug), there’s not going to a “gotcha” when using the keychain API. Just realize that the keychain is just a fancy encrypted database, and follow best practices for what you should store, and when you access / write to it, like any other DB.
I want to store sensitive data in an iPhone application but also have it be unlock-able via touch ID. I've thought of some options, none of which fully accomplish my goals and would like some advice on implementation.
Password protect app and encrypt data - Store only data encrypted with the user's password. Ask for password every time when decrypting to view data. I don't see how Touch ID would work in this scenario. It is secure but a pain to enter in password every time.
Password protect app only - Store raw data and only allow access if the user supplies the correct password / touch ID. This accomplishes the user experience I want but is that poor practice? Will Apple ultimately reject this method because the sensitive data is not encrypted? Keep in mind I am only storing data locally, there is no cloud/web server.
Scenario 1 with cache - The user enters in their password once a day, data is fetched, decrypted and then cached. The user need only authenticate the app while the decrypted data remains in cache. Clear cache if application is closed or a time limit is reached.
What does everyone think?
You have a few options.
Assume the user has their passcode enabled, and know that that means the DB is encrypted when the device is locked. For some cases, this is enough.
Encrypt the Core Data using Encrypted Core Data. FYI, this does work, but it has lots of limitations and bugs. We used it in an enterprise app and I regret using it.
Move away from Core Data to SQLite with SQLCipher. This is what I prefer now.
Bear in mind that you still have to deal with the DB key if you do per-app encryption. You can do this in a number of ways.
In many cases, you can just store the key in the Keychain and that's sufficient.
You can also require passcode/Touch ID/Face ID when launching your app/accessing the keychain item
Finally, you cal require the user to enter the passphrase
Regardless of your choice, use a key-derivation function such as PBKDF2 ~100,000 times to make brute forcing harder. Never store the actual DB key (which is derived).
I am working on the app that require protection screen for the app.
This screen looks like :
I already done all features expect one. It is proper saving of the pin code.
I read about iOS Keychain and think it is quite suitable approach to save sensitive information.
But I would like to hear opinion from others is it enough? Or what should i use to protect this (pin code) information.
Now it is working like:
Set
Pin -> Keychain
Get
Keychain -> Pin
Also I consider hashing:
Set
Pin->Encode->Keychain
Get
Keychain->Decode->Pin
Saving a PIN is similar to saving a user password - one should never do this in plain text even when you store it protected like in the keychain.
At least save it as salted hash, better use a password hashing scheme (one-way security function designed for processing passwords and PINs) like PBKDF2, bcrypt, scrypt or Argon.
In most cases the keychain should be enough. But there is no 100 percentage solution. If an attacker has access to the hardware and software you can only make it harder to get the data, not impossible.
That means in your case an attacker already needs access to the device and the device pin code / touchid (if set) to install a jailbreak. Only then it's possible to get access to the content of the keychain and your stored data inside.
An additional encoding of your keychain data requires to store the key for the encode/decode somewhere. You have to save it somewhere else, e.g.in the user defaults, but the keychain already has the highest security level. Encoding makes sense for the real user data (the data you want to secure with the pin: access token, file encryption password, ...), because for these data it may be importend to destroy them in app deinstall/reinstall process. The user defaults will be removed when deinstall, the keychain not.
Scenario: User deletes app and sell his/her phone without resetting it in device settings. Buyer installs jailbreak -> old data in keychain should be garbage/unreadable.
Conclusion:
Think about it: What user data do you wanna secure with the pin? These data are also located inside of the keychain, even if it's only an access token for web requests or a password for an encryption. You don't need a higher security level for the pin than for your data ;)
In case of a pin your solution should be enough. But it's imported that your real user data should use the same security level or a higher one.
Update
There is a higher security level than the keychain: "Secure Enclave". It's mainly used for saving the touch id informations. Apple do not documented it, so I wouldn't recomend to use it yet.
There is a project called Tidas to make it accessible for the community.
As we know OS X needs master password to unlock keychain and decrypt all data that is stored there. In general master password is stored in user's brains so there no any direct IT ways to compromise this password.
At the same time iOS makes some simplifications and it doesn't require master password that known only by user. So I became interested how is logic for iOS keychain unlocking and data decrypting implemented and found such explanation in Apple docs:
In iOS, an application always has access to its own keychain items and
does not have access to any other application’s items. The system
generates its own password for the keychain, and stores the key on the
device in such a way that it is not accessible to any application.
As I understand iOS generates master password by itself and stores it in some specific place.
My question is: does anybody know or have any ideas what is it place or way that used for storing master password that guarantees preventing from any IT attacks or third party accesses?
(I found some similar questions like this, but there are no any specific information.)
You can find a lot of information in the Apple iOS Security Whitepaper
Essentially the passcode is "tangled" with a device specific ID that is not available to executing code in order to generate keys. The keys used to unlock files and the keychain are kept in memory while the phone is unlocked (or after first unlock for some protection classes) but are discarded on lock or reboot (again depending on the protection classes) but the passcode itself is never stored in memory or a code accessible file system.
I am making a app where I need to store some login details.
I searched over internet and found usage of NSUserDefaults has some security issue.
As for keychain, how much data can I store for a single app?
The other option using sqlite also has some security issue.
About application update, how can I preserve data in the next application update.
So which one should I go for?
NSUserDefaults is a big NO for storing any secure data.
If it is only pertaining to user's username & password,i.e sensitive information, then Keychain is the best thing to use.
For other kinds of data(not sensitive) you can use Core Data to store information.
When an update takes place, you can explicitly copy data that is present & import it to your update.
Keychain data as such remains available to the app, after an update.