I'm designing a REST API and I have some problems in terms of security for authenticating the user. For authentication I don't want the password to be send across the network in plain text.
To bypass this problem I could send a SHA-256 hash of the password (with the username as salt), so the password is never sent in plain text. In my database I will be storing the following hashes: SHA256(password + salt) and I'll compare if both of the hashes match.
The problem with this option is that I'll have a hash computed with a fast hash algorithm and the salt is not random.
In security the best practice is to use a slow signature algorithm, with a random salt (like bcrypt).
The slow algorithm is not a problem, i could use bcrypt on the client side, but for the salt i don't know what to do:
So i can see 3 options, but none are sastisfying:
Is anybody has a better solution or some advices?
There a couple of advantages to the approach of hashing on the client side. One of them is the server never gets the real passwords, so if the server is compromised in any way, it still won't get the real password. The other one is, it can lighten the load on the server side if you're planning to use slow hashing.
However, hashing passwords is designed to protect you in case the database is breached and hashes are stolen. This means if someone gets a hold of the hashed passwords, they could still impersonate users by sending the hash. The implication is, even if you hash on the client side, you still need to re-hash on the server.
The other potential downside is that this could alienate part of your userbase that doesn't have JavaScript enabled.
To address your points:
Bcrypt need a salt with a defined size so i can't put the username
Don't use the username as a salt. Salts should be unique, and a username (and derivations thereof) is certainly not unique. By unique I don't mean just unique to the server, but unique everywhere. Use a cryptographic nonce instead.
If i'm using a random salt, how the client will know the value of this salt before computing the password's hash?
Just have the server send the salt (nonce) beforehand. You could do this on the client as well, but the Javascript doesn't have a CSPRNG as far as I know, and you'd still need to send the nonce back to the server.
I send the password in plain text (I'm using SSL) and i store bcrypt in the db => still vulnerable to man in the middle
SSL was designed to prevent man in the middle attacks. Unless it's broken somehow, that's not going to be a problem.
I use SHA256 and send the hash where the salt is the username (still using SSL) => the hash in the db are less secure
Don't use username as a salt. And like I said before, you have to hash on the server side regardless of whether or not you did it on the client side.
I use bcrypt and I have a two step process: i ask for the salt for a given user and then send the hash of this user (still using ssl) => by trying to log in with an other username i can obtain his salt, not awesome
Not awesome indeed.
I think you might be conflating/confusing a few issues here:
Hope this helps!
hash_val = HASH(HASH('username') + 'password')
is stored server-side. nonce = HASH(RAND())
client_hash = HASH( nonce + HASH(HASH('username') + 'password'))
and sends it back to the server. In this way the hash sent over the wire is used only once and you're protected from 'replay' and MITM attacks.
Also, look into something like PBKDF for storing passwords rather than just hashes, it makes both bruteforcing and rainbow tables completely impractical. Here's the PHP implementation I'm using since it's not in PHP yet .
If possible create API Key and secret key (API username/password, obviously unique for each user) to use API. You should give an option in your site interface to activate/de-active the API access as well as option to re-generate the API Key and secret key. Here, on this interface users will see the API/Secret key of the API.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.