Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

What is the current way to authenticate users in a mobile/global fashion? In other words, assume a mobile application. And if there is a database server in the backend, how would these users typically register/login? Is there a current standard for non-domain, non-enterprise authentication?

I was thinking just having a basic username/password combination, and hashing (and salting) the password on registration and login, and passing that over the wire to the cloud database. That gets a little fuzzy with password resetting, emailing, etc. though.

Is there an easier way (API, methodology, etc.) or more-accepted way to do this? It's simple, but that simplicity is a good thing, I think. I don't need the complexities of other membership frameworks. I'm more curious if this is an accepted and secure approach.

I am aware of ASP.NET's membership model, but the complexity is just way too much for a one-dimensional security model (users and auth, no need for roles, authorization, etc.). Not to mention, outside of an ASP.NET application, what would be used?

share|improve this question

1 Answer 1

up vote 2 down vote accepted

In general, if your mobile app is based on remote web services, you should establish a secure connection (ssl/tls) to the remote server and pass the username/password directly to the server for processing on the server, not on the client.

I presume this is some kind of a web server. You are almost definitely not going to be connecting directly from your mobile app to a bare database server, right?

What you would not do would be to hash the user-supplied password on the phone, then pass the hash across the wire for comparison on the server. The authenticating server's job is to confirm that the remote party knows the correct password for the supplied username, not that the remote party knows the correct password hash for the username.

Otherwise, an attacker who might have gotten access to your credentials database could just pass a username and password hash and never need to know the actual password at all. Oops! :-).

If you're going to roll your own authentication on the server, then you would need to store at least 3 fields:

  • the username
  • password hash
  • salt (randomly generated entropy, unique per user)

You should also consider storing:

  • a password hash version id, so that you can switch to an upgraded algorithm in the future without automatically invalidating all of your existing passwords

  • a password expiration date/time (or some variation of this concept) so that you can expire passwords when you need to, or have them auto-expire after a certain age

The salt and password hash are byte arrays when fully reconstituted in computer memory. Convert them to Base64-encoded strings for storage.

Simply hashing the password is considered insufficient now:

  • even if you use salt and even if you use a substantial hash algorithm like SHA256 or SHA512

    • using straight hashing without salt was what got a certain large business networking service into so much trouble with their latest user account breach
  • dictionary attack methods using the GPU's on powerful video cards combined with dictionaries or rainbow tables makes it necessary to make password comparisons slow enough not to be worth the effort

  • MD5 just isn't up to the task at all, and hasn't been for a long time

  • SHA1 has theoretical exploits and is considered to be weak now (at least potentially, just a matter of time before it's exploited)

  • SHA256 or SHA512 are better, but still too fast

Use an algorithm actually designed for hashing passwords, such as bcrypt, scrypt or PBKDF2.

  • These types of algorithms build on hashing algorithms like SHA1 or SHA256, plus HMAC algorithms, then iterate many times (perhaps thousands, or more) feeding the result of each iteration back into the algorithm to make it infeasibly slow for a brute force attacker to run billions of comparisons from a dictionary/rainbow table, while still being fast enough to reasonably verify individual legitimate user logins.

  • You can vary the number of iterations to suit your own purposes (speed vs. security).

  • An attacker will have to know what algorithm you use, and also know the number of iterations you have chosen

  • The authentication algorithm id comes into play here; if you increase the number of iterations, then you break all your existing user credentials unless you have id'd the algorithm and continue to support the old algorithm (say, PBKDF2 with 1,000 iterations) for existing passwords while requiring the new algorithm (say, PBKDF2 with 10,000 iterations) for new and updated passwords

If the processing load becomes too much for your server (presumably a web server), you can offload authentication to a separate server.

A lot of the cool kids are doing PBKDF2, although bcrypt allegedly makes it more difficult for a GPU-based attack to compare many passwords quickly. Scrypt may be an improvement over bcrypt. I'm not making any value judgements here. Do your own research on these. PBKDF2 may be FIPS compliant, for example, while bcrypt and scrypt are not, but FIPS compliance may not be a requirement for you.

share|improve this answer
    
If you're using a heavy-duty hashing algorithm for passwords (recommended!) be aware that the cost is quite high for legitimate users. It doesn't matter too much if you're using it once to establish a session, but if you're passing full credentials on every API call (to make things more stateless) then the cost of authentication can become really significant, and a transparent cache in front is very useful. (Learned this the hard way.) –  Donal Fellows Mar 25 at 11:25
    
Ouch. Yes, you don't want to punish legitimate users. If you have your password authentication tuned to take a significant chunk of a second to authenticate the user (1/10, 1/4, 1/2 second, ...), paying that performance cost for every individual API call would not only be punishing to individual users, but it would be a real impediment to scaling your app to a high degree of concurrency. Regardless of whether you're passing an authentication token or actual credentials on every call, it is also vital to use SSL/TLS to protect the entire session, to protect against MIM attacks. –  Craig Mar 25 at 12:29
    
Ok, perfect. So I think what I'm going to go with is caching a token and passing that with calls to the web service so it doesn't need to authenticate with every call. –  user3175663 Apr 1 at 23:54
    
@user3175663 You should also put a TTL on your auth tokens and even renew them occasionally during a session. If somebody manages to intercept one of your auth tokens, they should not be able to come back to your system later and spoof it with the stolen token. –  Craig Apr 8 at 7:35

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.