In an API I have there’s a requirement to use an authentication method other than OAuth2 or any kind of token generation which requires making an extra HTTP call.
With this in mind there’s this https://www.xml.com/pub/a/2003/12/17/dive.html
I’ve only stored passwords as hashes and used functions like password_verify
to know the user sent the proper credentials without actually knowing the password stored in DB.
WSSE requires to encrypt with SHA1 the credentials being sent, which means the API needs to retrieve the password in plain text to recreate the digest and compare it to the one sent by the user.
So, how should I be storing this password if the code needs it to recreate the hash?
Should I have something like a master password and store them encrypted instead of hashed?
Most of the information I’ve found about WSSE is very very old, and some implementations have it marked as deprecated, do you know any other type of standard authentication where the user can generate the token instead of having to make an extra HTTP call?
As for client side token generation…
Never trust the client.
Say you hash the password client side. At this point, you have to have static salt (which can be extracted from clients), and the hashed result becomes the password.
All of this greatly weakens the security.
If the client sends a username, and the server returns a salt, then it’s a bit more secure. At least this way the salt can be randomly generated for each user.
But, it’s an extra API call.
You could use the username as the salt. This makes things a bit better, but you open yourself to being rainbow-tabled for usernames like “admin”. Also, the salt doesn’t change when a password is updated.
Here’s a SE post that kinda pertains to what you want:
https://security.stackexchange.com/questions/93395/how-to-do-client-side-hashing-of-password-using-bcrypt
This one has a section on client side hashing:
https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords/31846#31846
Edit:
Client side key generation isn’t worth it. There aren’t any good implementations.
I think one of the answers linked above alludes to the following solution:
Do a double salt:
Username & password get bcrypted (or similar) together in the client. The username-as-salt reduces the parallel of brute force attacks to a single user (ie if an attacker has a bunch of hashes of different passwords for the same user, they can brute force them all at the same time - they know the salt)
Username and hash is sent along with the request (the hash essentially becomes the new password without leaking it in plaintext in server logs, gateways, proxies etc.).
The server then retrieves the users salt from the database, hashes it again using the appropriate salt.
This way, at least the data at rest is fairly well protected. But I’m not a crypto guy. I have learned to follow the herd when it comes to authentication and security.
And I don’t think there is actually a decent way to do this that actually provides the kind of security required these days.