1

What is the best way to handle encryption for passwords?

I'm trying to send a password via a NSURLRequest. The passwords are encrypted at the database level on the server.

  1. Should I send the password over as clear text and then when it reaches the server, encrypt the password and then check if this password matches the encrypted password in the database.

  2. Should I encrypt the password first and then just check this encrypted password matches the encrypted password in the database?

fes
  • 2,465
  • 11
  • 40
  • 56

3 Answers3

2

You should never send a password over an unsecured plain HTTP connection.

Using TLS (successor of SSL) as stated by j0k would be your way to go, if it's possible you should use it whenever possible instead of inventing your own schemes. If you simply use one-way TLS/SSL (i.e. only the server authenticates itself, client stays anonymous) then you will save yourself the trouble of handling symmetric encryption keys on the client side.

If you properly set up your TLS on the server then you may simply transmit the user credentials unencrypted. TLS as a protocol handles encryption on the transport level so you as a developer need not care about it any longer.

Another thing you should probably do is not storing the passwords in encrypted form, but just storing a salted hash of them (SHA-1 or something adequate) in your database. This way you'll never be in danger of compromising your user's passwords.

emboss
  • 38,880
  • 7
  • 101
  • 108
  • thanks i shall look into salting as well. my only issue is that this needs to be interoperable between iphone and a .net server. I've just tested this [link](http://stackoverflow.com/questions/538435/aes-interoperability-between-net-and-iphone) and will need to check your salted link. – fes Jul 10 '11 at 17:13
  • You will have much less interoperability problems if you do not encrypt the passwords at all - as I said, TLS does that for you, so you're free to send them in plain over the TLS connection, TLS takes care of the encryption. That's the beauty of it: you can work as if you're not doing any encryption at all, the encryption will take place on the transport level, nothing changes on the application level. – emboss Jul 10 '11 at 17:20
  • Interesting, I'll look into TLS now. But isn't that a security issue if you leave passwords unencrypted especially at the server side? I guess you can just send the password over clear text on the secured channel and just let the server side deal with it so to avoid interoperability problems. – fes Jul 10 '11 at 17:31
  • Exactly. The server receives the password unencrypted (please note that encryption actually *does* happen, it's just on the transport layer, not on the application layer, cf. [osi layers](http://en.wikipedia.org/wiki/OSI_model)). So you don't need the application-layer encryption. What you would do on the server is simply salting the plain text password, hash it and store it in your database and then discard the plain text. – emboss Jul 10 '11 at 17:36
  • I am just thinking of doing the following: user enters username/password on iphone device, it gets sent via tls or ssl to the server, server picks up the credentials, encrypts the password and make sure it matches in the database. Do I really need to salt the password before it gets sent to the server? I'm not sure why you would need to hash it at the server level. I guess its just a one way authentication. If they forget their password, I issue a new one. – fes Jul 10 '11 at 17:44
  • You would salt and hash on the server - here's the [motivation](http://phpsec.org/articles/2005/password-hashing.html). – emboss Jul 10 '11 at 17:49
0

Given how you're doing it, it doesn't really matter which approach you use. The comparative approach is exactly the same. If you're just comparing a string to a string, there's no difference between "foo" and its encrypted counterpart, e.g. "74$#4uc".

If you're looking for security, there are a few things you can do, but they're all going to require work. The simplest probably would be to post to the URL using SSL, if that's an option for you.

csano
  • 13,266
  • 2
  • 28
  • 45
  • So are you saying neither is secure than the other? SSL is an option but I thought to test the above first but just couldn't think of a way to encrypt correctly as like you say both just appear to be the same. – fes Jul 10 '11 at 16:30
  • @j0k -- there is a great deal of difference between "foo" and its encrypted counterpart; namely, the ability for an attacker to collect an unencrypted password. If the password has been salted in the encryption, dictionary attacks against the encrypted password won't work, either. – Chris Gregg Jul 10 '11 at 16:55
  • @Chris Gregg - If OP is encrypting it in the app and comparing it directly to an encrypted value in the database on the server, which is what is implied by the question, there's no real difference. – csano Jul 10 '11 at 17:03
  • @fes If you can use SSL, then that's what I'd go with. – csano Jul 10 '11 at 17:05
  • @j0k -- I see what you mean, but your answer reads like it doesn't matter if you send the unencrypted password across the network. If you clarify it to say that the *act of comparing* is similar, then I'd agree that it doesn't matter. – Chris Gregg Jul 10 '11 at 17:08
  • thanks im looking at the ssl route now through my test server. i have created a ssl certificate and now using https. does it simply mean i can now send to this https a clear password and as its a secure channel, I can just encrypt this password and check at the server level? Or is it recommended like @Chris Greggs suggests encrypt to locally as well. – fes Jul 10 '11 at 17:11
  • @Chris Gregg - I've updated my answer to indicate that the comparative approaches are exactly the same given how OP has identified his implementation. – csano Jul 10 '11 at 17:19
0

I would encrypt the password locally and then send it over to the server. You always want to limit passing around plaintext passwords, for security reasons.

Chris Gregg
  • 2,376
  • 16
  • 30