0

I need to encrypt a password in Swift and send it to my web server to store in the database. Any best practices? I've seen AESCrypt.encrypt(userPassword, password: API_AUTH_PASSWORD) but I'm not really sure if this is sufficient (salted, etc.). Also, on the server itself, how would I go about comparing hashed passwords for login authentication? I'm using PHP. Basically I'm asking if there is a generally accepted encryption method in Swift to hash and check passwords on a PHP-based web server.

Ryan Bobrowski
  • 2,641
  • 3
  • 31
  • 52

2 Answers2

6

See this question. You should understand the implications of hashing on the client side:

  • Pro: You can use a higher number of rounds, creating a stronger hash.

    For reference, 1Password uses a minimum of 25,000 rounds of PBKDF2-HMAC-SHA512. Your users likely won't be using diceware, so you'll want a higher count if possible.

  • Con: You're locking yourself into a specific algorithm & round count.

    The hash output will in effect become the user's password. You won't be able to tweak things later. This means a weaker hash over time, as computing power increases.

    Also, since the hash grants access to your website, it should be stored in the Keychain.

    Using a salt (appname + username for example) should prevent a server breach from affecting any other sites.

    As the link mentions, you would probably still want to use a "fast" hash (SHA-512 for example) on the server. This limits the damage if only the database is compromised.

    On the server, hashes should be compared in constant time with hash_equals. password_compat has code for earlier versions of PHP.

    defuse recommends a random salt on the server-side when using client-side hashing.

The alternative & more common scenario is to do all hashing on the server.

For PHP, see password_hash, password_verify, and password_needs_rehash.

If you're using an older version of PHP, there's password_compat.

  • 1
    I'm doing that already - but that means I'm sending the password in plain text. I guess the answer would be to secure the server with https? – Ryan Bobrowski Jun 06 '15 at 03:35
  • 2
    @itstrueimryan Yes, use HTTPS. –  Jun 06 '15 at 03:49
  • Agree that (quick) hashing on server side is a requirement for client side PBKDF2ing, but I do not believe adding a salt on the server side adds any value on top (client side salt required though). I have written a research paper on exactly this topic: [Method to Protect Passwords for Databases for Web Applications](https://eprint.iacr.org/2015/387.pdf). I also expect that the web community will be moving to something like this in the future -- a number of people had similar ideas, it is really just a a matter of analysis and getting it right! – TheGreatContini Jun 09 '15 at 02:34
  • @TheGreatContini I don't see any obvious benefit either, but it's also [suggested here](http://security.stackexchange.com/a/23033). If you use as many PBKDF2 rounds as you can tolerate, along with a salt that includes an app-specific & user-specific value, that should be enough to guard against lookup tables & anything else I can think of. I'm not a cryptographer, so I may be missing something. –  Jun 09 '15 at 08:40
  • Thanks for the reference. I did cite the David Wachtfogel reply on the research paper above (reference 21 in my paper), but did not notice the comment from Motoma. I really wish people would give the reasoning behind their claims because as far as my analysis indicates, there is no value added for server side salting when you are doing it on client side. If they think otherwise, then I wish they would present the argument! – TheGreatContini Jun 09 '15 at 09:08
1

Best practice is to NOT store the password in your database.

You should perform a one-way hash function such as SHA and store the hash value instead. When you need to authenticate a user, hash the user-entered password and compare the the hashed values. Use a salt value in your hashes to further increase security.

picciano
  • 22,341
  • 9
  • 69
  • 82