I'm working on an iOS app that will also have a web component. When a user creates an account, their password will be salted and hashed. I already have the hashing algorithm working on the web-side.

When a new user creates an account in the app, should the iOS app hash their password and send that to the server to be directly inserted into the database? Or should their password be sent to the server in plain-text, and hashed there? Should it be encryted in-app, sent to the server, decrypted, then hashed? I'm just not sure what the best and most secure protocol is. I guess the same question goes for authenticating an existing user trying to sign in.

Also, at this point I don't have SSL set up on the server, but I'm certainly willing to do that if it helps with this.

4 Answers 4


Use SSL to handle the communications over the internet safely, then hash the password it on the server. Otherwise the password hash just becomes the password, as far as the service is concerned, and an attacker that gains access to your database can log in as any of your users as if their passwords were stored in plaintext. SSL is vital in order to prevent your users' credentials from being intercepted on the network.

  • This is an excellent answer. I'd love to know if you'd say it is also "standard practice". Or is there any widely-accepted reasons for hashing passwords on the client side?
    – algal
    Feb 11, 2014 at 19:26
  • 2
    I personally think hashing on the client and sending the hash is completely fine. Sure the hash 'becomes the password' for that service but to get the hash the system will be compromised already. Plus plaintext passwords never leave the client in that scenario. Also, most apps "login" once then get issued an api key or perhaps a session key from the server. The api key, if taken, will allow full exploit of the service as the user anyway.The api key is typically stored. The sent hash (on client side) will be ephemeral and gone after login.
    – Montdidier
    Oct 23, 2014 at 5:15
  • For a mobile app as in this question it makes a lot of sense to hash on both client and server side so that server never even receives a plaintext password. I recommend having a look at medium.com/@harwoeck/… Jul 27, 2021 at 9:38

Why can't it be both? When the user enters their password (as a new user or during login), hash it client-side, then send it over a secure channel to the server, which will hash it again before doing any comparisons. Redundant, distributed security; as long as the attacker isn't "on" the machine on which the plaintext password is entered (using a keylogger etc), he will have to break multiple hashes/encryption layers, and no one node in the system knows everything that needs to be known to get from the plaintext password to the hash stored in the DB.

The hash performed on the server should be an expensive one, like bcrypt or scrypt; the one on the client should still be a crypto-strength hash, but something faster like SHA-512 is fine.

  • 2
    Both is better. Ideally plaintext password never leaves client.
    – Montdidier
    Oct 23, 2014 at 5:20

The most secure protocol currently available involves public key cryptography.

  • generate a "server" private key on the server. The private key never leaves the server. Somehow get the corresponding public key to the app. Using HTTPS (TLS) is the most common way of handling this. Typically the web server sysadmin pays around $100 to get the public key signed by a certificate authority; but this is not technically necessary.
  • generate "device" private keys locally on the app, when the app is run for the first time on that device. The private keys never leave the device. (Best practice is to generate both a "signing" private key and an "encryption" private key, and then public keys derived from them). Somehow get those public keys from the app to the server, perhaps at the time the user creates an account.
  • Use some sort of mutual authentication. I've been told that the (optional) "client authentication" part of TLS ("Client-authenticated TLS handshake") is one way to do this.

Alas, it's a bit tricky to handle a single user who has several devices (each with their own private/public keypair).

  • 2
    Whilst this is reasonably sound advice, it doesn't really answer the question. Certificate distribution and management doesn't fit the standard convenience model that users expect, which is what OP was asking about.
    – Polynomial
    Nov 22, 2012 at 9:02
  • @Polynomial: All websites that use "HTTPS" already somehow handle certificate distribution and management. Are you seriously saying that websites using "HTTPS" are nonstandard and too inconvenient for typical users?
    – David Cary
    Nov 22, 2012 at 13:44
  • 2
    No. You're talking about client certificates, which is a totally different concept entirely. You cannot distribute client certificates (including private key information) in the same way without some serious changes to browsers, or manual installation of client certs by users.
    – Polynomial
    Nov 22, 2012 at 13:47

It sounds like you are looking for a password-authenticated key agreement (PAKE) protocol. My understanding is that there are several software libraries that support "secure remote password protocol" (SRP) or some other PAKE protocol, including GnuTLS, OpenSSL, Bouncy Castle, and other TLS implementations.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .