How to communicate with a server that needs authentication? - ios

At the moment I'm storing both the username and password for communication with the server (through Alamofire) in the iOS keychain. However, every now and then the keychain returns nil when trying to retrieve these items. Therefore, storing the username and password in the keychain is not a reliable option. Is there a better way to communicate with the server? Maybe a session cookie or something?

Do you have freedom to modify the server-side code? If so, you could check out JSON Web Tokens: https://jwt.io/
If not, instead of the keychain we could use NSUserDefaults (https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/). But remember that this is an interface to store user preferences, it is insecure to store passwords in it. That's why you should consider using tokens.
See this related question: NSUserDefaults or keychain is better to save username and password in iPhone app

Related

Where is the best place to store the key for encryption a password in keychain?

I want to implement a second security, because when the phone is jail broken the keychain is vulnerable and I don’t want my passwords to be secure only by the keychain. That’s why I want to encrypt the password by me before save the in the keychain.
The reason I want to encrypt it is because the server for login accepts a plain text password not hashed. I had the idea to have a rout for encrypting and when the user logins for first time, the password is send as a plain text and after that encrypted.
The encryption to happens on the backend and the backend can decrypt it. Is this a good idea, because when the user changes his/her password he/she needs to enter the old one as a plain text and I call the encryption rout on which I sends the password. It is responding me with an encrypted one of it and I am
comparing them. So in the keychain is only the encrypted one.
Is there a better way if it is where to store the key if I am encrypting the password on the device? If it is a static hard-coded field it is not OK. If it is in the keychain too, and on the server it is possible to have a different encryption key for every user. What is the best way to do it?
There is no good answer to this question, as the threat vector is too broad. You want to protect some secret information even if the device security is compromised (someone other that the user of the phone has jailbroken / hacked it). The best information about this can be found in the article Secret Management on iOS.
TL;DR: “Don’t (but if you must, obfuscation wouldn’t hurt).”

Restful Credentials Storage IOS

I have a service that connects to a database through a restful api with username and password. My question is what is the best way to store those credentials in my iOS app so that they cannot be seen by any attackers (gain access to our database)? Is storing the username and password in a private variable enough? Do i use the keychain? If i use the keychain how do I use it and is it possible for those users to gain access to that information?
Keychain is the best way to go if available. I use UICKeyChainStore for my own apps.
Its actually dead simple to use that API. Here is an example from their page:
UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:#"com.example.github-token"];
keychain[#"kishikawakatsumi"] = #"01234567-89ab-cdef-0123-456789abcdef";
Another option would be to store only the password hash in the NSUserDefaults. You can read about best practices for hashing here.

Obtaining FB password with users permission

Is it possible to obtain a users fb password, with granted permission?
I'm using it in a project that allows users to keep their sensitive data locked using their fb account.
It's for an iOS application, and right now I'm able to collect a users email, through the Facebook iOS sdk, and password, through a login "workaround", but I'm not sure if the app is going to get rejected due to infringement of facebook's and or apple's legal rights.
No, it is not possible to obtain a user's Facebook password.
I am not sure if the app will be rejected but I would personally avoid this solution.
I suggest to use the user's facebookId instead of the user's email.
If the secured data are stored in the app:
You only need the facebookId.
If the secured data are stored on a server:
Of course, checking only the facebookId isn't secure enough because anyone with a precise facebookId could login with it and get access to the "secured" data on your server.
What you need is two parameter to identify a user through your app:
The facebookId of the user
A secret key
You can send the secret key in your header request (or as a URL/BODY parameter if you want). It ensures that your server is called by your app an not from another source (a hacker).
What I would do to be more secure is to hash these two parameters in SHA1 so that even your request isn't readable. Then all you have to do is compare on your server the same key hashed in SHA1 with the one received.
For hashing a string to SHA1, here is a link : http://www.makebetterthings.com/iphone/how-to-get-md5-and-sha1-in-objective-c-ios-sdk/

RESTful stateless service and KeyChain. Go stateless or nor?

I am planning to make a ASP.NET Wep API server and a IOS client.
From what i have read, the KeyChain is the only place to store IOS sensitive data such as passwords.
Considering a RESTful stateless service: the username and password must be sent to the service with each request.
This stateless service seems to bring the following two extra operations with each call:
Go go KeyChain and get credentials
Validate the credentials
Q1:Does that mean that for every request password must be retrieved from the KeyChain and passed to the server?
Q2: That makes me wonder, go stateless or not?
The keychain is the place to persistently store sensitive information, yes.
If you are using a username and password and keep it for the duration, storing it in memory (RAM) is typically ok. If you wish to remember it for next time so the user must never provide it again, you must store it in the keychain.
Typically you store the password in memory (even for a session) once retrieved from keychain.

Access Tokens Persistence Best Practices (iOS)

Should access tokens for services like Twitter and Facebook be encrypted?
In particular, should tokens be stored on the the device's Keychain vs. UserDefaults? What are some possible security issues that could arise if a user's device is stolen/taken
This is what I have come up with so far.
Pros of Keychain:
Encrypted
Cons:
No way to clean up when user removed app
Pros of UserDefaults:
Kept inside the app.
Cons:
No encryption.
Your UserDefaults 'con' needs amending: no encryption by default. You can encrypt the content yourself using e.g. CommonCrypto, but it needs additional work over storing the plain text.
The point of an OAuth token is that someone who owns that token can use the relevant service without having to present credentials. Therefore, you should protect it like you would protect the password if you had to store that instead, as it has the same value.
If the user's device is stolen, then unless they have passcode-locked their device the thief has the capability to use your app as the user in either of the situations you describe. If you do not encrypt the access token, then they additionally have the capability to extract that and replay it from code under their control.

Resources