15

I am creating an app and a website for a project I've got going, but I'm not sure what I should do about login. This is not a "I'm a noob and I want an app with login"-question. I am somewhat experienced with both web-, database- and app-development, but I've never actually touched the subject of security before other than by application templates.

What I'm imagining is a 'simple' login-system like Skype, Facebook, NetFlix, really any app that you are able to log in to, which also has a website to log in to.

A part of my question is towards the security of the process. My initial thought is that a password in clean text should never be sent over internet, which makes me believe that the passwords should be hashed/encrypted on the phone, as well on the website, when logging in. I've done some small-time hashing/encrypting before, but just by using sha1 and md5 to "convert" the text. What's the proper way to do this? With my current knowledge, I assume that if I'm using md5 to encrypt a password, anyone could decrypt it with md5 too, but that I could use a SALT(?) or some form for altering key. Is that how the "big boys" are doing it, or is there a secret passage I don't know of?

Now onto the real question.. How should I store a login securely?

What I've tried: When making a "test-project" in Xcode for this, I simply created a class User with a field for username. When "logging in" by entering a username and password, I simply sent a POST-method HTTP-request to my .php-page, which simply performed a SELECT * FROM User WHERE Username = '$_POST['username']' AND Password = '$_POST['password']'; If the database returned one row, then the password was correct, and the page could print out the user in JSON or whatever. When the device got the successful login, I converted the user-object in the app, now containing the username (and potentially UserID, E-mail, Address etc.) to NSData*, and using NSKeyedArchiver and NSKeyedUnarchiver to save and load the user, never to authenticate again. If the user clicks "Log out", I wipe this 'archive'. This works, but I sense that it's not a particularly secure way of doing it. If so, why exactly is that?

(Our back-end is currently Google's App Engine(java), which has support for OAuth. Some are recommending this, but we can't find any proper documentation that makes sense for our plan with custom users)

Sti
  • 8,275
  • 9
  • 62
  • 124
  • I dealt with this using a webview to display the website login form, and, on successful login, setting a cookie with an authentication token that was assosiated with the user in the backend. – Linuxios Jan 14 '14 at 00:30
  • @Linuxios I read somewhere that some apps were rejected by Apple for doing this. Anyway, even if this is 'allowed', it's not really what I want. I want to create my own iOS-UI login form. Thanks anyway. – Sti Jan 14 '14 at 00:36
  • Rather than using hashing algorithms (md5, sha) not designed for use with passwords, considering using something more secure (like PBKDF2). See SO post here:http://stackoverflow.com/q/8569555/558933 – Robotic Cat Jan 14 '14 at 00:38
  • @Sti: Really? Id like to see that if you can find it. Thanks. – Linuxios Jan 14 '14 at 01:03
  • @Linuxios This is not one of the posts I was thinking of, but I guess it's the same reason.. http://social.msdn.microsoft.com/Forums/live/en-US/b6fc19b4-d19b-47dd-a4b4-2623856dfb1e/ios-app-rejected-due-to-login-web-view?forum=messengerconnect If you search for that particular response from Apple (the log in interface must..), you find more on google. Mostly from Apple blocking a Microsoft-app or something.. Might be purely rivalry this one though. – Sti Jan 14 '14 at 01:16

3 Answers3

2

Password Transmission

The easy way to secure this is to just send passwords over SSL. If you set up an SSL certificate and do all your authentication over https, all the back-and-forth communication is encrypted by the transport layer. Note - md5 is not an encryption algorithm, it's a weak hashing algorithm - don't use it for security.

Storing Logins

Your passwords should be stored in the database as a salted hash (random salt, with a collision-resistant hash function such as SHA256). Don't store the plaintext version of the password anywhere. If you're using PHP on the server side, you can use the new password_hash() function or crypt() to generate and compare your salted hashes.

If you're communicating securely over SSL, you should be able to just use the session capabilities of your web server to keep track of logins (e.g., $_SESSION['user_id'] = ...).

Sam Dufel
  • 17,560
  • 3
  • 48
  • 51
  • Ok.. Even though you have some great and relevant information here, I think you slightly misunderstood my "Storing logins"-question. I meant on the device, in the app; how does the user stay logged in on my service on the device. "What's the standard procedure as to where to store the credentials locally." "Should I use, and if so, how to generate and use tokens." "Should I send credentials along with every server-request" etc. And we're using Java on back-end, by the way:) – Sti Jan 16 '14 at 20:19
  • I think you misunderstood my answer, then :). I believe JSP has built-in session handling, so if you use an http library with a persistent cookie jar in your app, logins will be stored exactly the same way as they would be in a web browser. The server will automatically create a session token and send it to the app as a cookie; the app will automatically send that cookie along with all requests. – Sam Dufel Jan 16 '14 at 22:09
  • Oh ok.. Well, we're not using JSP. We have a Google App Engine back-end with Java, with it's own API/library, and I don't think they use cookies. I might be wrong though, and we might be able to make it ourselves.. But do most apps with login really use cookies these days? All I read about are tokens, what's the difference? – Sti Jan 16 '14 at 22:53
0

If you want to securely store your username/email/address, or anything else for that matter, the built-in keychain is the only Apple-happy way to go.

Have a look at SSKeychain (or PDKeychain or UICKeychain) and extend it to include each property you'd like to store. Generally it's used to store username and password combinations, but can be extended to store arbitrary data safely.

As for passing secure data to your server, do it over HTTPS.

I can provide examples if you'd like.

Tom Redman
  • 5,592
  • 4
  • 34
  • 42
  • With this, what is the best practice for authenticating? Should the device send the username and password as arguments every time he performs an action connected to the db, and then authenticate every move? – Sti Jan 14 '14 at 16:55
  • Generally, after a successful login a session id cookie is returned. This cookie is passed forward on every call to the server (happens automatically) and the server determines whether the user is authorized to make that request. This is the same as most session based login systems. You can make the session cookie valid indefinitely if you choose. – Tom Redman Jan 14 '14 at 19:33
0

Another option is to add some sort of OAuth or XAuth login process.

That way, you are not storing any passwords, but only so called "Tokens". The tokens expire, and can be revoked.

Not storing the username and password at all is the best way to secure them.

Alex

below
  • 929
  • 6
  • 26
  • One problem with using *Auth is you are trusting that the other service enforced good passwords. Also you are trusting their security and they may be a much bigger hacker target That is why I do not use it. – zaph Jan 14 '14 at 13:15
  • We're currently using Google App Engine as backend(java), and OAuth2 seems to be supported and is recommended by many, but we can't find any documentation that makes sense for our purpose. Have you used App Engine? – Sti Jan 14 '14 at 16:41