2

I'm doing an "Remember me"-function in my app, and I've came across solution where you store all credentials in Keychain and solutions where you just store the password in Keychain? The stored password I just want to use upon authentication, however I use the username a lot more, and instead of having to fetch it from the backend, I could just get it from disk. Is one of the mentioned solution better than the other?

Upon authentication I just do this, if I go with the split solution:

let hasLoginKey = NSUserDefaults.standardUserDefaults().setBool(true, forKey: "loginKey")
    NSUserDefaults.standardUserDefaults().setValue(username, forKey: "username")
Recusiwe
  • 1,594
  • 4
  • 31
  • 54
  • Anyway is fine, if you store in keychain i think it will last even after the user delete the app, otherwise there are no actual different on performance, and you shouldn't get it from the disk ALL THE TIME, just get it once and use it through the app life time as a property – Tj3n Aug 30 '16 at 10:55
  • If username is for example email address then it should be kept secure. It depends upon your org's security review. They might not like keeping user name unencrypted. When you delete the app, UserDefault will be deleted as its inside the sandbox but keychain content will remain, as keychain stores data outside sandbox. So when user will install the app again, you will have his password but not username(it was in UserDefault). You he would need to login again. –  Aug 30 '16 at 11:04
  • Does I take more to retrieve from Keychain than from NSUserDefaults, memory-wise? – Recusiwe Aug 30 '16 at 11:11
  • Do not use NSUserDefaults for anything that needs to be the least bit secure, for secure items store them in the Keychain. If you have a data blob then encrypt that and save the key in the keychain. WRT time cost I refer you to: [Donald Knuth](https://en.wikipedia.org/wiki/Donald_Knuth) "The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming." If there is a performance issue profile to find it and then fix it. – zaph Aug 30 '16 at 13:28

1 Answers1

13

You asked for "recommended." The recommended practice is not to store the password at all. Design your service so that it will accept an access token unique to that service. You accept the username and password, the server hands you back an access token, you store the access token, and you throw away the password (and possibly the username). A standardized way of doing that, with common server and client frameworks available, is OAuth. (And much as OAuth drives me a little crazy because of its complexity, it really is a fine protocol, and it's very standard.)

The correct place to store the auth token is the keychain. As Zaph notes, "double-encrypting" the secret doesn't buy you anything because you now have another secret (the encryption key) to store. Where do you store that? If you have a more secure place to store your encryption key, put the token there. If it makes you feel better to obfuscate it a little bit with a hard-coded key, fine, but the security benefit is pretty minor.

If you cannot design your service in the recommended way, and must store the raw password, then store it in keychain. See above. All the same arguments apply. Keychain is the most secure place on the phone. That doesn't mean it's unbreakable. It just means it's less breakable than any other place you would store things.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610