views:

127

answers:

4

So I'm working on a mobile platform application that I'd like to have users authenticate over the web. I was wondering the best way to do security. The user is sending a password for HTTP to a php server wich authenticates against a mysql database on the same server. Obviously I don't want to send the password in plain text over the internet, but I also don't want to do 2 SHA hashes.

This is what the server looks like (in pseudocode)

$pass = $_POST['pass'];

if ((get PASSWORD where USERNAME = USERNAME) == SHA($pass)) return PASS;

This is pretty standard and I don't think there's any other way to do this. But I was wondering how I should prepare the data before sending it over the internet.

+4  A: 

You could use SSL if your client app supports it.

Pekka
A: 

As Pekka pointed out, SSL is your best option.

As an alternative, using SHA in JavaScript is pretty easy, fast, and it's already been written. Here's an example and here's a library: crypto.js

Justin Johnson
There's no need to implement it yourself. There are very good libs that already do that. For example Crypto.js, I wrote about it here: http://techpriester.tumblr.com/post/547863016/crypto-js-by-jeff-mott
Techpriester
I swear to god there's an example library in my link ;) Let me rephrase that so it's clearer.
Justin Johnson
A: 

For regular non-critical system most websites send the password in plain text over the Internet during a http post request. The password is then server side encoded by SHA1/MD5 and checked against the value in the database.

You can also use https basic authentication, this will encode the password with a simple algorithm. But although it does not send the password in plain text, the encoding is so simple that it’s very (very!) easy to crack. But by using basic authentication, you cannot use a regular login form, you will need to do with the browsers support for basic authentication (not very user friendly!).

If you need more security most websites just install a server side SSL certificate that you buy at an ISP (for example godaddy). This will make it possible to access you’re login script over an SSL encrypted connection. This solution is considered secure (as long as the password is not easy to guess or stolen).

An other interesting, but uncommon approach, is to do the SHA1 encoding in JavaScript before doing a (Ajax) post request to the server (JS sha-1 example). In theory, this could deliver quite reasonable security…

And if this all is still not enough you could consider installing client certificates or a response-challenge system with a calculator or SMS.

Kdeveloper
I don't agree with doing the sha1 encoding before sending it. This way the sha1 hash just acts as the password, and anyone sniffing network traffic can just send the hash to the server without needing to know the original password. Plus this either makes it inaccessible to people not supporting JS, or it means your server has to detect what kind of password was sent (hash or no hash).
Carson Myers
The server could send the salt, the client could calculate the salted hash, append a random string, hash again, send back the second hash and the random string, and the server could check it by appending the random string to the stored password hash and hashing again. It is a bit complicated to pull of (you need two requests to log in), but is reasonably safe against an attacker who can monitor the communication but can't pull a man-in-the-middle attack. Of course, he would then steal the session cookie anyway.
Tgr
@Tgr: How does the second hash with the random string help make things more secure? If the first hashing (hash the password + the salt) is vulnerable to an replay attack, the second hash would not help at all because the attacker would replay the same "random" string.
Cosmin Prund
@Codmin Prund: that can be avoided by controlling how the random string is generated. It could include a timestamp, for example. Anyway, if you use SSL, you can just send the password in the clear, and if you don't, hiding the password won't save you. Bottom line is, if you want security, use SSL. (Though there is some advantage to hashed passwords without SSL: the site will be still easy to break into, but it will become harder to find out your actual password, and use it to attack other sites.)
Tgr
Thanks for the comments. @Carson, good point! Also thanks @Tgr this will take away the problem @Carson pointed out. But I agree, this JS solution is way to complex; it's much easier to just use a server side SSL certificate.
Kdeveloper
+5  A: 
  1. If you want security, YOU. MUST. USE. HTTPS. With a proper, non-self-signed certificate. Whatever you do, identities that are authenticated in unencrypted communication will be trivial to steal. (Never mind the password, the attacker can simply steal the session cookie that is provided with every request.)
  2. Hashing is worthless in itself, you must salt it. (This is not really related to authentication - it is a second layer of defense for the case when someone steals your database. Which will probably happen sooner or later if you become a promising target.) Use bcrypt with long random per-user salt, sha* is insecure because it is too fast.
  3. Use methods that are already in use by large, security-aware projects. Those methods have, to some degree, withstood the test of time. There are challange-response based methods that avoid sending the password in any form, but crypto is hard, and it is very easy to implement secure algorithms in an insecure way. Use a good security framework (e.g. PHPass), don't rely on code that is not widely in use.
Tgr
+1 for a much more detailed answer than mine.
Pekka
Thanks for the answers guys. I'm not too experienced with web programming, I guess it's time to look into learning a bit more about security. Are there any guides that can give me the overall picture of how these technologies work together? Just for more information, this is an android program where the user must create a username/password in the application, and then I'm going to implement a web interface for the user to be able to interact with the phone. So the only time the password is being sent over the internet is on user creation.
Falmarri