Password processing for public APIs? - security

I do not understand some concepts of storing/processing passwords.
For example, our site has a public api for mobile application(iOS, Android, etc) with provided authentication.
No doubdt, we must not store raw passwords in the database and we must not send raw passwords between client and server, so we use hashes and salt.
This way, we encrypt passwords on client and send hashes to server. But, what if a "black hat" steals password hash and authenticates with it to server api?
Should I hash passwords on client, send hashes, then hash them again on server?
What is the common solution of this problem?
Great thanks in advance.

You can use SSL to protect communication channel between client and server, and send password unencryped.
Second approach - to store hashed passwords (without salt) in server, and when authenticate - get random token from server (that will expire in some minutes), calculate hash from client password and use calculated hash to encode received token. Then send encoded token to server. Server does same operation but use hash stored in database instead calculating it from password. This approach has cons - needs to store password raw or hashed without salt. Or send salt to client with token.
But, what if a "black hat" steals password hash and authenticates with it to server api?
This problem is solved by using tokens that will expire after usage.

Do a lightweight hash client side (no salt), then rehash the hash (with unique salt) server side. Store the salt and (doubly) hashed password.
The server side hash should also use something like pbkdf2 or scrypt that can perform thousands of hashing iterations to deliberately slow down the hashing process. This helps prevent brute force attacks of the hashes by slowing down the attack process.

Related

Can you send a hashed password back to the user in plain text?

So I am dealing with a website concern, I am a intermediate level programmer and I was shopping on a website that I have heard other friends use. When I signed up for my account, they sent me my password back in plain text to my email. I always thought that in a html form, if you hashed a password and sent it to the server, there would be no way of sending a password back in plain text. I am assuming the website I made the account is hashing the password, but I have no way of knowing. I'm not a security expert or anything, but I am pretty sure they aren't hashing the password and probably storing my data in plain text on their servers. Is my conclusion correct?
If your password is sent to you during the registration process, it can be that it's sent right when the server receives it and still has it plaintext, and then it gets hashed and stored properly.
This would still not be the best practice though, cleartext passwords should not be sent over insecure channels, like in email.
Of course in this case it's not possible for them to send it again in another request. If that happens, that really means they are not storing it hashed.
If it's properly hashed and secure they should not be able to see it in plaintext. If they could access it easily then so could hackers.
There is another way to store the passwords, encryption. In this way, the application server stores an encryption key to encrypt users' passwords and store them on the database.
When users try to login, they encrypt the new incoming password of the login attempt to see that it is matching.
In case of lost of the passwords, they can send users' password back to them by decrypting it using the key on the application server.
If the application server is compromised, the attackers can access all passwords as the same way the application server does.
By no means, they should send back to users, their passwords. If users don't remember, they have to force users generate into a new one.
For more discussion see Difference between Hashing a Password and Encrypting it

Security of an authentication algorithm

I am making a little script in python, in which a client has to authenticates to the server. The idea is that an attacker cannot authenticate himself by listening to the network, without knowing the password.
Despite any good practices, I am trying to make my own secure authentication (it is only for personal use).
In my current algorithm, the client and the server share :
the password that authenticates the client
an encryption key
the encryption algorithm (AES with pycrypto)
It works as follows :
The server generates a token
The server encrypts the token
The encrypted token is sent to the client
The client decrypts the token
The client encrypts the set (password + token)
The encrypted set (password + token) is sent to the server
The server decrypts (password + token)
If the received information corresponds to the shared password and the token sent by the server, then the client is successfully authenticated.
In this algorithm, the client and the server share 2 secrets : the password and the encryption key.
I am wondering if it would be secure to do like this :
The server generates a token
The server sends the token to the client (in plain text)
The client encrypts the token, and returns it to the server
If the decrypted token is correct, the client is successfully authenticated.
In this case, the server and the client share only one secret (the encryption key). From my (small) knowledge of AES, I think that an attacker should not be able to guess the key with the token and the encrypted token, nor to guess the encrypted token without owning the key.
So my questions are: do you see any flaws in my algorithms? Is the second as secure as the first?
Thanks for your help
I am not a crypto expert (shout out to https://crypto.stackexchange.com), but AES is meant to assure confidentiality, and your method does not prevent non-repudiation. In other words, I can't read the contents of the token, but I can intercept your message and send the same one to the server to "authenticate" myself, right? (https://en.wikipedia.org/wiki/Replay_attack) Additionally, someone in the middle could modify your message and potentially cause problems, since again, AES assures confidentiality, but not integrity of the message. Aside from those core issues, there are subtle mistakes you can make when implementing this that can cause issues that are very difficult for you (and me) to detect, but possible for attackers to sniff out.
Perhaps when combined with an HMAC, you can overcome these weaknesses... but I would have to encourage you to not "roll your own" crypto scheme and perhaps all you need is HTTPS to secure the communication between the two devices (and a pre-shared token/key/password to prove identity). If you do decide to continue down this route, I would also encourage you to do significant research and having a security expert review your code/implementation before using in any sort of production environment. If this is just for fun/research, that's another story.

I don't understand very good the benefits of the salt and hashed password in the client side

I have readed this article:
https://crackstation.net/hashing-security.htm
It is said that in a web application, always it is needed to hash the password in the server to ensure that the hash is correct. But if the client hash the password and sends to the server, the server what to do is hash the password, so how can the server hash the password if what it receives from the client is the hashed password?
The other doubt that I have is the basic steps that it is needed to do:
Retrieve the user's salt and hash from the database.
Prepend the salt to the given password and hash it using the same hash function.
Compare the hash of the given password with the hash from the database. If they match, the password is correct. Otherwise, the password is incorrect.
Well, the server get the password from the client, use the salt with the password from the client, hashes it and compare with the hashed password from the database. Well, how the salt is always the same for this user and it get from the database, if a middle man get the password, can use this password and authenticate in the database, because the server will use the salt and get the same hashed password. So no matter if it is the real user or the middle man, the server allow the access.
Another option is if the server receive the hashed password, it just needs to get the hash from the database, so it avoids to hash, saving resources. Then the client instead of send the password, send the hashed password and the server compare this hashed password from the client with the hash of the database. here, a middle man can get the hashed password too and use it to authenticate. At the end, is the same that if the user send the password.
I don't see the benefit to salt and hash the password, because if a middle man attack the connection, he can authenticate in the database. So I think that the important it is to ensure that the connection is safe, and then is the same to send the password in plain text, because the connection is secure. But perhaps I don't understand something because I know that salt and hash the password it is a common practice.
The only real benefit that I see to hash the password if one attacker get access to the database, because he can not get the password from the hashed password, but if a attacker access to the database, he can get access to all the information, so I guess the less important data is the password.
For that reason I am wondering, Is it not enough with a secure connection? because if an attacker can access to the connection, then he can access to the password and can authenticate in the server. If the attacker can not get access to the connection, then why to hash the password in the server? Is waste resources to hash the password because is a hard process.
Thanks.
Hash algorithms are asymetric, which means that you can generate the hash but going from a hash to the login credentials is much harder.
Keeping the password in an unclear form in the database prevents bad-intended people who can access it to get the clear password and authenticate as the user.
Moreover, it's not by accessing the hashed password record in the database that would allow an attacker to steal the account but by accessing the server source code to determine how the password is generated and then be able to regenerate it.
Considering that firebug for example allows you to access the client source code, you don't want to perform the password generation on the client side.
PS : If you implement SSL and HTTPS, then the packets of your request are encrypted.
We need salts. When you try to login, you hash your password client-side and send the hash to the server. They compare your hash to their hash (they also still have your password in plaintext).
What if an attacker captures your hash in transit? A good hash algorithm won't let them go from the hash back to the password, but hackers can use rainbow tables... They can try tons of passwords until they find a password with the same hash.
To stop this from happening - from the attacker from finding your password - we use a random salt. We add some random stuff onto your password before we hash it so that the hash isn't the same as the hash for your password. We send the new hash along to the server with the salt in plaintext. The server adds the salt to their copy of your password and they hash it. If the hash matches what you sent them, you login.
But since the salt is always changing, an attacker will have a hard time cracking your password.

Text Pass word Security

Hello anyone knows how security is provided to text password in Google or in any website. In my web-app i am encrypting password using AES algo. Should i need provide more security? If yes what kind of security is needed? How text passwords are managed/ made secure by Google or any web site?
Do not encrypt passwords.
Instead, you should hash passwords using a slow salted hash, preferably bcrypt or scrypt.
You should secure your forms (also username and password fields in Login or Registration forms in HTTP transactions) and also the important data(s) in your database by hashing them with SHA-1 or MD5 algorithm (with salt)
For your login and registration forms you should use SSL connection in order to prevent man-in-the-middle and also sniffing attacks.

Storing password in tables and Digest authentication

The subject of how to store web site users passwords in tables has come up several times on SO and the general advice is to store a hash of the password, eventually an HMAC hash. This works fine for Basic authentication or for forms based authentication (really the same thing). My problem is that I must provide also Digest authentication, aimed at the automated tools connecting to my service. I've been looking at this problem and as I see it, the only hash I can store is the HA1 part of the Digest: the hash of username : realm : password. This way I can validated both Basic/forms and Digest.
My problem is that I don't see any benefit in doing so. Now indeed an attacker cannot use Basic or forms based authentication if he gets hold of my password table (since he only has the hashed value and he needs to send the clear password), but nothing prevents him from using Digest authentication and give a valid response to my service challenge: he simply starts from the pre-computed HA1 from the table and continues the crafting of the response from there (ie. the same thing I'd do to validate a user on the back-end).
Am I missing something? Does the addition of Digest requirement basically makes the storing of hashed passwords a no-op from security pov, an obfuscation at best?
The reason I am using pre-computed hashes is not protection against attacks, but to secure users privacy.
Attacker can indeed authenticate, but he cannot (easily) see password of my precious users and compromise other services they are using etc.

Resources