IOS Keychain Service - ios

I'm new to iOS development and programming, so please bear with me.
Correct me if I'm wrong but, conceptually, an app can access any items in the Keychain that are associated with the app. It is my understanding that hackers can manipulate the code of an application like "Jailbreaking" to do the hacker's bidding.
In that case, is it possible for the hacker to simply access all the elements of the Keychain by adding additional code?
For example, if my app is checking authorization by comparing the inputted value with the Keychain stored password, could the hacker simply modify the code to get the Keychain stored password? If so, how do you guard against this?

Yes. Anyway, you should be storing the password hash, not the password.
You cannot protect the user against themselves. It's their data. You can't keep them from reading their own data.
The alternative is to store data on your server instead of on the device.

Related

Setting credentials in code can still be compromised even after keychain security

I would like to store username, password, auth token in my iOS app so that I can connect to my db, perform operations etc. I notice that the recommended way is keychains. The reason for this is that a malicious hacker if got your ipa by jailbreaking or something else can read your code and look at the username/password.
But my question is once the user logs in and I save their username and password in keychain, I set the credentials in the code itself so how is this secure? If a hacker gets an ipa and opens up the code, they will see where I'm setting the password anyway or if there a place to store this so no one can really see it.
I have been reading a lot about how secure keychain is and I definitely agree it is, but setting the value in keychain has to be done in the code itself which worries me if someone gets the code and can see it.
Reference: https://medium.com/ios-os-x-development/securing-user-data-with-keychain-for-ios-e720e0f9a8e2
You can add an extra layer of protection by detecting if App is running on a jailBroken phone
How do I detect that an iOS app is running on a jailbroken phone?
Also keychain provides protection to passwords or private keys as the data is encrypted.
An application can access only its own keychain items, or those shared with a group to which the app belongs.
https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html

Using Touch ID on iOS to encrypt data

What I'm trying to do
Basically what I'm trying to do is figure out a way to encrypt data using Touch ID.
Sadly I've not found a way to create an encryptionKey with Touch ID, since the LAContext API only returns a aye/nay response.
Why I'm trying it
I'm implementing different log in methods in an app. The supported log in methods are a password, PIN-code and Touch ID. The user is free to choose whatever log in method he/she wants.
Only the password however, is send to the server which will authenticate the user. As such, only the password is stored in the keychain.
The encryptionKey, used to first encrypt and then store the password in the keychain, is created using whatever method the user chose as log in method.
If the user chose to use a PIN-code, the encryptionKey is derived from that PIN-code, the same can be said when the user chose a password as log in method.
My question is:
How can I fit Touch ID in this picture?
I've searched on the internet, but only found what I already feared.
Since iOS only returns a true or false from the Secure Enclave, it's impossible to create an encryptionKey.
I know the keychain is encrypted by itself, but for security reasons (please don't elaborate on this) I need an encrypted password stored in the keychain.
EDIT:
The reason behind storing data encrypted in the keychain is because the keychain can be breached by jailbreaking a device.
And since the app I'm working on allows users to view (mostly) corporate sensitive data, I need to take even jailbreaking into consideration.
Use the kSecAccessControlTouchIDCurrentSet or kSecAccessControlTouchIDAny keychain access control attributes to protect your encryption key in the keychain. Using this API will fail if the user does not have Touch ID enabled (or the device does not support it), and using kSecAccessControlTouchIDCurrentSet will fail if the user modifies the set of fingerprints. In case of failure, you can then fallback to your normal authentication UI, such as pin code or password entry.
See the WWDC 2014 711 Keychain and Authentication with Touch ID talk and WWDC 2015 706 Security and Your Apps for more information.
As a general note, do not store data in the keychain. You should only store passwords, encryption keys or credentials, and use those to decrypt data stored on the disk.
I know, this question was posted back in 2015, but I researched for the same problem. As Far I know, it's actually not possible.
I have found this Quote on the 1Password website concerning this topic:
Don’t jailbreak your device. Someone with physical access to your device could theoretically access the secret that 1Password stored in the iOS Keychain. However, that would require unlocking the device, jailbreaking the device (so that something other than 1Password can read the iOS Keychain data that belongs to 1Password), and defeating the obfuscation of the Master Password. If you jailbreak your device, you are willingly defeating one of the strongest defenses against such an attack.
So, simple answer: It's not possible :(

Storing multiple username and passwords credential in keychain

I'm creating an application that requires the user to log in, I've read that it's a bad idea to use NSUserDefaults so I want to go with either storing the data inside a sqlite databaseor use keychain access. My app will show data based on what user is logged in from that device, so if two people have an account with me they can log in from the same device and it shows the data pertaining to their log in. Is it possible to store multiple log in credentials with keychain or should I go with an sqlite database so that I can properly connect it to the data pertaining to that log in? If keychain is the best way can someone point me to a demo that lets you store multiple users in the keychain.
Update
The reason I need to store multiple user/pass in the keychain is because after they log in they are required to create a four digit pin to use within the app. As of now if someone else logs in it uses the previous pin instead of asking for the user to create a new one. Should I add an if statement to check if the user is in the keychain and if they are not there call the pincontroller. Using the keychain how can I tell which pin belongs to which user?
iOS provides a very secure way to do this via the keychain. It's really the only way to store this type of information so I strongly recommend against rolling your own solution.
If you want to access the keychain you can use one of the many libraries available for this. Here are two:
https://github.com/soffes/sskeychain
https://github.com/secondgear/SGKeychain

Storing authentication tokens on iOS - NSUserDefaults vs Keychain?

Which is the place I should be storing tokens for when the user logins in to a service? I'm not saving passwords (obviously where I'd use the Keychain) but just the token. A lot of places say just use NSUserDefaults but some people on StackOverflow seem really keen on the Keychain.
Is NSUserDefaults fine?
I would highly recommend you use the keychain - it's exactly what Facebook do for storing their session tokens.
NSUserDefaults is not secure or encrypted - it can be easily opened and read, both on device and when synced to a Mac. So whilst user defaults is a good place for things like preferences and config info, it's not a good place for anything sensitive, like passwords.
Session tokens should almost always treated the same as passwords, so you should store them securely in the keychain, where they'll be encrypted. Apple have some sample code (GenericKeychain) that shows a basic implementation, and you'll find other examples by searching StackOverflow. Hope that's helped you out.
NSUserDefaults can be used without any problems (for tokens!).
Please check documentation https://developer.apple.com/documentation/security/keychain_services
Keychain Services are invented to “secrets” that the user explicitly cares about, i.e. passwords, private keys or even secure notes, i.e. clear credentials. But access tokens are temporary hashes generated after user entered password and have limited time. And even if stolen, the malefactor cannot completely stole the account - the owner can login on another device and previous access token will be reset. So, formally there is no forbiddance to store access tokens in UserDefaults.
The data from UserDefaults can be stolen only if the device is stolen itself, but I think the security level of the content is much lower than the physical device itself. I think user would not worry about the token in that case, but about the device.
However, it’s a good practice to store it in Keychain, but it’s just an excessive (!) usage of security and usually recommended by random users in the Internet and it’s not required by Apple. There is no documentation by Apple there they say that tokens must be stored in Keychain (if you can find one, then please comment one below).
So, the answer is - you can use both. However, if you app is operating with content that costs a lot in contrast to stolen iPhone, then it's better to use Keychain, but it's just a recommendation.
All sensitive data should be stored in the keychain.
UserDefaults is for small pieces of data like user preferences.

How to store non-standard web authentication?

In the web API my app communicates with, the authentication process is designed in the following way:
The user enters the name of the group that he/she belongs to.
The server sends the list of group members.
The user chooses a user name and types a password.
My app sends a hash constructed of the group id, user id and password to the server to validate the credentials and in case of successful validation uses this hash in further transactions.
Having this process, I do not get standard NSURLConnection messages like connection:canAuthenticateAgainstProtectionSpace: or connection:didReceiveAuthenticationChallenge:.
I can deal with it per se, but when it comes to securely storing the credentials, I get confused. Is there a way to do this via some built-in iOS SDK methods or I have to write the hash in a file manually, for example? What's the proper way?
The keychain seems the best option to store the user's credentials/hash.
Check out http://developer.apple.com/library/mac/#documentation/Security/Conceptual/keychainServConcepts/iPhoneTasks/iPhoneTasks.html
And https://github.com/ldandersen/scifihifi-iphone/tree/05e64ff2814a8192c43f1f81eb8e09dc3764fa18/security
Be aware that while the keychain is probably the safest place in iOS to store this kind of data, it isn't entirely secure. But considering the data you want to store, it's probably well enough.
Edit: Look at http://overhrd.com/?p=208
You'd be able to access the data on your keychain with simple calls of this nature:
[Keychain setString:#"hashhashhash" forKey:#"userHash"];
// later on…
[Keychain getStringForKey:#"userHash"];

Resources