Where is Password for iOS Keychain unlock stored - ios

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.

Related

Is it enough to save Pin code (string) value to iOS Keychain to be secure?

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.

How to store critically sensitive information such as secret, key, token, encryptionKey in iOS application

When we talk about securing iOS application we often forget to secure most critically sensitive information such as secret, key, token, encryptionKey. This information is stored in iOS binary. So none of your server side security protocol will help you.
There are lots of suggestion that we should not store such information in the app but store in the server and get it via SSL secured web service call. But this is not possible for all application. E.g. if my application does not need web service at all.
In iOS app we have following option to store information.
UserDefault: Not appropriate for this case
String Constant: Not appropriate for this case. Can be reverse
engineer to retrieve or just use strings command
Secure Database: Store in Secure and encrypted Database. But again have responsibility to secure database username and password.
KeyChain: Best to store critical info. But we cannot save information before installing the app. To store in the keychain, we first need to open the app, read from some source and store in the keychain. Not appropriate for our case either.
Custom Hash String Constant: Not to directly use secret, token, key from service provider (mixpanel, paypal), instead use hash version of that information from custom key. This is also not perfect solution. But add complexity during hacking.
Kindly send some awsome solution to this problem.
If you don't want to use your own backend then use Apple. You can configure On Demand Resources and keep data file with your key, token, any secret on Apple server. After first download you can write this data to Keychain which is secure enough. I'm guessing networking between iOS and Apple server is also secure enough.
On-Demand Resources Essentials
Accessing and Downloading On-Demand Resources
1) Internet Connection Required
1.1) Push Notifications
Great way to have a secure data exchange could be to use (silent) push services from Apple, those use the apns and send data through https - more Details 3.1
1.2)
A more or less similar approach is also used when distributing new user certificates to already deployed applications, if a reinstall of the application is no opportunity AND the application requires a working internet connection anyway.
Downside: working network connection required and basically the information is coming to the application, when it is already being executed => seems not to be appropriate for your case. (see step 4)
2) Static data (as there will be no exchange without network connection / communication partner)
Encryption of data with private key being provided in the bundle itself. Whether it is now a string or a hash, which can be reverse engineered with functions you got emebedded in your application.
Since iOS9 it is pretty hard to decompile iOS applications and basically you will mainly have a look into the provided header-files. So if you had such a function, string, hash value or whatever, make sure you got it in your .m-file!
But again: if the information is not device or user specific, just a secret across your own micro environment, valid across all devices, you would have to provide the encrypted data AND the decryption method in the same bundle, if there is no update process / information exchange or something else, you can think of.
Good for encryption:
iOS System.Security https://developer.apple.com/reference/security
or simply openssl
The difference between your described keychain approach is:
You got a value, which WILL be encrypted and stored securely.
(2) describes the approach to have an encrypted and stored (in bundle) semi secure value, which WILL be decrypted
3) Information exchange
You describe critical data, which was hashed by another instance. Great! - Make sure, relly make sure, the instance you are talking to is really the instance you expect to be (Network Hooking prevention with ssl certificate pinning etc, but even here you might have intruder (men-in-the-middle)). And you will (probably) have a certificate being provided in your application bundle, to ensure the authenticity of the communication server - here you go again, data that is supposed to ensure a secure process between certain instances of your micro environment. Nevertheless, this data is being provided in your application's bundle.
3.1 Secure Information Exchange extended - Silent Push
Make use of Apple's servers to exchange your secrets for this purpose. If you just need to exchange small data chunks. I would recommend to use silent push notifications to the user, those do even work without explicit permission from the user. Huge advantage: In case your secrets or keys change, you can inform users as soon as possible about the change. They will likely only need the change, when they receive new data, which should reliably work in most cases. Exception: Data exchange in local networks or via bluetooth, in this case I would recommend to provide a notification to the user to have the requirement to update a local decryption key. Or exchange the key in this format as well. Once again: I am leaking some detailed information about your environment architecture.
Downside: You don't know, whether a user just used your app for the first time, until the user "tells" you so.
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1
3.1 Secure Information Exchange extended - In App Purchase
Use a frree In-App Purchase for the user to get the data to your phone. Good point here: you can provide larger data chunks easily, as this should be an active request by the user, the user does expect certain processing time and should also be aware of the fact to require a working internet connection.
Downside: User would have to select this on purpose. Up until then the app would not work accordinly.
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction.html#//apple_ref/doc/uid/TP40008267
So, it just slightly differs from the approach (2) in its basic idea.
In short: Can you provide additional information, what kind of data you need to encrypt/want to store securely and whether you will have a network exchange or not?
Would need some more information here :-)
I would like to emphasize once again that an application on iOS is not that easy to decrypt anymore, even decompiling would not get everything, you expect it to get. For instance decryption tools like dumpdecrypt were only working properly up until iOS 8.4
It seems to me that the best way to do this is using the built in CloudKit. You can save your secrets in the CloudKit Dashboard and then fetch them on startup. Since CloudKit is only a transport layer you'll have to store the app secrets in the KeyChain.
I know you mentioned the KeyChain not being ideal for your use case (not sure why), but this is a good way of not including the secrets in your app. You can't get around fetching your app secrets from another source.
CloudKit access is secured using the system iCloud account and if there is no iCloud account you still access the iCloud servers securely. Another added benefit of this is that you can change your app secrets at any time, so if you want to be even more secure you can implement a rotation schedule.
Learn more about CloudKit
Cocoapods-keys might be a best option.
From cocoapods-keys doc's
Key names are stored in ~/.cocoapods/keys/ and key values in the OS X
keychain. When you run pod install or pod update, an Objective-C class
is created with scrambled versions of the keys, making it difficult to
just dump the contents of the decrypted binary and extract the keys.
At runtime, the keys are unscrambled for use in your app.
The generated Objective-C classes are stored in the Pods/CocoaPodsKeys
directory, so if you're checking in your Pods folder, just add
Pods/CocoaPodsKeys to your .gitignore file. CocoaPods-Keys supports
integration in Swift or Objective-C projects.
Check out this link for installation, usage and more info : https://github.com/orta/cocoapods-keys
I agree with #Lobsterman and believe that the best way will be to use a combination of these.
Don't include the secret information in the app initially.
Deliver the secret key either as in-App purchase content ,on-demand resource or send it through push notification. This will add the benefit of changing the key periodically if you want and the change will take effect without any additional effort.
Add the entry to keychain access once the content is delivered.
If the data is extremely sensitive then it should never be stored offline on device because all devices are crackable. If you still want to store on device then keychain is one option for storing data securely, However it's encryption is based on the pin code of the device. User's are not forced to set a pin, so in some situations the data may not even be encrypted. In addition the users pin code may be easily hacked.
A better solution is to use something like SQLCipher which is a fully encrypted SQLite database. The encryption key can be enforced by the application and separate from the user's pin code.

Data Protection, Keychain and Core Data's Sqlite files

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.

keep corporate app alive in background

I am developing a corporate app that will be publish on an internal store.
The app is just supposed to keep in memory some credentials but I can't store them on the device for security reasons.
I want the app to stay in background as long as possible but I don't know what is the best solution knowing that I won't have to publish the app in the AppStore.
I read about the option in plist Required background modes, but I don't know which option is the most efficient for my situation.
Firstly, you don't need to keep running app in background, second you can store "those [secret] credentials" in keychain store with some encrypted format, SHA1 or MD5 or any other cryptographic hash functions can be use for this, third the benefit of this is you can access to them from your different apps as well (by using the same encryption key to decryption and accessing keychain store item), at last when you no longer need it, you can even delete it. The only thing you need to keep secret is keychain store key (which you used to store credentials) and also your encryption key (to used with cryptographic hash function).
There's are several libraries available to easily manipulate data in keychain store, here's the one, and here's the solution to apply MD5 or SHA1.

How does iOS data protection work

I have a quick question:
I downloaded an iOS application that uses the NSFileProtectionComplete class to protect a sqlite file that contains sensitive information.
According to the iOS security documentation (http://images.apple.com/ipad/business/docs/iOS_Security_May12.pdf), when a device (iPhone/iPad) is paired with the laptop, the laptop obtains the escrow keybag from the mobile device . The keybag contains all the class keys necessary to decrypt information on the device.
However, I noticed that when I pair the device with the laptop and use iExplorer to browse the file system, the sqlite file is only available when the device is unlocked. When the phone is locked (still paired) the file is not readable. Files which are not using NSFileProtectionComplete can be viewed while the device is locked.
If the escrow keybag contains all the class keys to decrypt information, why do I have to unlock the device to access it through iExplorer?
I'm using iOS 6.0 on an iPad3 and used the ios-dataprotection tool (https://github.com/ciso/ios-dataprotection) to determine the data protection class used by the files.
iOS Application: AccountVault
File: PointMinder.sqlite
Any help will be appreciated.
Thanks.
From documentation file you've linked:
Complete Protection (NSFileProtectionComplete): The class key is
protected with a key derived from the user passcode and the device
UID. Shortly after the user locks a device (10 seconds, if the Require
Password setting is Immediately), the decrypted class key is
discarded, rendering all data in this class inaccessible until the
user enters the passcode again.
So device should be unlocked if you want to access that files. That is how Apple made it.
Edit: Found in "Hacking and Securing iOS Applications":
Protection class keys are master encryption keys used to unlock files based on their access policy.
Protection classes are the encryption mechanism used to enforce the access policies of files.
Some files are so important that the operating system should be able to decrypt them only when the device’s user interface is unlocked. These files’ encryption keys are wrapped with a class key that is available only after the user has entered his passcode. When the device locks again, the key is wiped from memory, making the files unavailable again.
Protection class master keys are stored in an escrow known as a keybag. The keybag contains the encrypted protection class master keys, as well as other keys to system files on the device. The system keybag is encrypted using another encryption key named BAGI, which is also stored in the effaceable storage of the NAND. Whenever the user authenticates to meet a specific security protection policy, the encrypted keys in the keybag can be decrypted.
So keys for that files are transferred, but are encrypted. When you enter your passcode, OS decrypt that key and it can then be used to decrypt files protected with it.
This works for me for SQLite databases in my app only, not for my other resources as I was hoping. BUT, I was having the same issues still being able to access the databases after locking the device and waiting several minutes with iExplore still open and device still connected. If I disconnect the iPad and connect right back in, iExplore forced to refresh I guess and I then could NOT access the databases. So not sure if it just has the old 'unencrypted' database info in memory or what.

Resources