Is it possible to verify a password hash against another password hash? - hash

Consider the following interaction:
A user stores their username and password on a web server. For the sake of security, the server records a hash of the password plus some unique salt.
While the user is using a client application, it makes a request to the server submitting their username and a hash of the password plus some other unique salt.
So you have the following information on the server and need to know whether or not the request is authentic:
The server's salt
The server's hashed password
The client's salt
The client's hashed password
Again ... client sends: clientSalt + MD5(clientSalt + password). Server has serverSalt + MD5(serverSalt + password). I don't want to know the password, I just want to know if the hashes were calculated from the same password.
Without knowing the password that was hashed, is there any way to verify that both hashes are of the same password?
My goal is to allow some form of secure authentication in a client-server environment without ever exchanging the actual password over the wire. This is just one idea I've had, but I don't even know if it's possible.

That would require unhashing the password, which is not possible. If the server receives: salt, md5sum, it can't see what went into the md5sum.
A challenge-response protocol would work instead. The server should generate a random value nonce and send it to the client. The client calculates md5(md5(password) | nonce)) and returns it to the server. The server verifies by checking md5(storedpassword | nonce).

No, you can't do this.
Once you add a salt into the mix it becomes practically impossible to compare hashes. (To do so would require "un-hashing" those hashes somehow before comparing the "un-hashed" data.)

Challenge-response authentication is probably the way to go, possibly using Kerberos, depending on your tradeoffs. One of the tradeoffs being the possibility for attackers controlling the clients to use compromised hashes to authenticate themselves.
Don't invent your own cryptographic protocols. Use one that is well-known and well tested. If possible, use an existing (vetted) implementation.

My goal is to allow some form of secure authentication in a client-server environment without ever exchanging the actual password over the wire. This is just one idea I've had, but I don't even know if it's possible.
For this, I advise looking into Kerberos: Official Site and Wikipedia

It's impossible. If you don't store password on the server, user must provide it.
OR
If you store password on the server, user can provide hash calculated using requested salt.

You will not be able to verify the hash with this setup.
If you don't want someone to see the password go over the wire, SSL is the easier way.
If you don't want to use SSL, you could check out SRP.
Additionnally: don't use MD5+Salt to store your password, use key strengthening functions like bcrypt or scrypt.

Related

Storing passwords on server

I want to do the following
User signs up to IOS app and provides username and password
Make a server call and store password in server database
When user logs in in the future, retrieve that password and check against the password that the user entered.
How can I do this in the most secure way possible? I was thinking of encrypting the password when storing in the db. When the user logsin, use the same encryption algorithm and compare against the db encrypted password.
NEVER ever store user credentials in encrypted (reversible) form. Currently best known way for checking user credentials is slow salted hash
for what and why please read https://nakedsecurity.sophos.com/2013/11/20/serious-security-how-to-store-your-users-passwords-safely/
However, don’t try to invent your own algorithm for repeated hashing.
Choose one of these three well-known ones: PBKDF2, bcrypt or scrypt.
As already commented you may outsource the user authentication to some reliable service (google, fb, aws cognito, ibm appid,...)
Have you tried looking into databases? I know that Firebase has an authentication component of their database for ios development, and you might want to try to look into it or other databases. Check out firebase at: https://firebase.google.com/

Why kerberos using hashes

Can you explain me the exact reasons and benefits of using hashes of password instead of the passwords themselves?
Because parcticly if you got hash of user you can authenticate as that user, and anyway the password is invisible.
It's more secure to store a hash of a password rather than a password itself (e.g. in keytab).
Kerberos only transfers over network encrypted Authenticator with its own copy of a secret key. Authenticator contains unique information about the client (for example, client name, client realm, the time on the client, and so forth). Each Authenticator is unique, because of the time information it contains.
So information transferred over network can't be reused (replayed later by an attacker), as Authenticator is unique and depends on time.
Hope this helps. With Kerberos you don't have password stored nor transferred over network. Which makes it more secure.

Using same password hash for account activation

I've used password_hash($pwd, PASSWORD_BCRYPT) to create a hash and store in the user table. It will be used for login verification.
Since hashing is a one way function,
My question is can I use the same hash as the account verification code in the activation email send to user.
Will it compromise security since knowing the hash doesn't reveal the password.
Yes, it would compromise security because an attacker with access to the email account (either presently or at any future point in time if the email is never deleted), could run a password guessing attack on the hash.
If would be better to generate a 128-bit key using a CSPRNG, this can be emailed to the user as is. On the server-side you would want to hash this using SHA-2 for storage, because that way if your activation table data was ever exposed, an attacker could not activate accounts that do not have valid email addresses. Note that no salt is needed for automatically generated keys of this strength.
This approach is fairly simple, and mitigates the risk in sending the password hash directly.

Store and retrieve password in database

I am developing an app which uses several API services, the API requires that I provide username and password for API transactions, unfortunately no API token :-( in-order to automate I need to store username passwords somewhere, preferably database, I cannot use hashing because I need to send the username/password to authenticate and process API request, hence I am wondering how to go about it.
If I use Zend\Crypt to encrypt and store the password in database and decrypt whenever required, would this be enough for security? is there something else I must consider?
Looking for pointers.
PS: I am using ZendFramework2 with Doctrine/MySQL for the app.
Usually you would use a token mechanism (like OAuth). If that's not possible, one would use TLS/SSL client authentication.
However, if you rely on plain passwords (on the application-level, I still guess the username/password tupel is transmitted over a secure connection!) and you want to store them encrypted, you have to think of a meaningful mechanism to get an encryption key for your scenario. Just generating an encryption key and storing it on the same machine in plain does not provide more security.
Without more information on your scenario it is hard to make a suitable suggestion.

Protection measures against hash cracking when transmitting hashed credentials using a nonce

I need to authenticate users using an api key, but before handling it over to them I need to check their credentials, obviously. I think the process needs to go like this:
client->server: GET /user?username=fred
server->client: nonce=XYXY
client->server: POST /login?hashval={hash(username + password + nonce)}&nonce=XYXY&username=fred
server compares the result of hash(username + passwordFromDB + nonce) with hashval and responds with the API-key if equal
But if there was somebody eavesdropping the connection, although it wouldn't be able to directly discover my user's password, since it already knows the username and the nonce, if the password was easy enough the man-in-the-middle would be able to match my hash by trying all the generic possible values for the password.(brute-force attack)
I know connection over HTTPS and a strong password would make this process secure, but are there any other recommendations or ways of making this process more secure?
Thank you
This is basically a form of digest access authentication and as such has its same limitations.
Since all the details to compute the hash are sent along with the hash, the only thing that an attacker needs to "reverse" is the password. If that is weak, then rainbow table or brute force attacks could crack it. The only way to delay an attacker is to have a very long and strong password.
But since you are using an API key for service authentication, as a man-in-the-middle attacker I would let you authenticate with a password and then just get the API key from the response. I assume you use the API key for authentication of the rest of the requests (just like a session cookie is doing for web applications)?
There are of course other variations of securing a service, depending on what you are doing, but actually making it secure means using HTTPS as you mentioned yourself.