On the login route i retrieve the password. How do i find the user with the matching hashed password in the database without fetching the whole user table and traverse it on the server?
In mysql every user has a hashed password from registering. I generated it like this: bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
If i execute the same method at login (for the same plain-text password) i get a different hash.
So something like this:
select * from User where hash_generated_at_register = hash_generated_at_login
Fails, even if the plain-text password used in the login and register step is the same.
From what i understand password checking in bcrypt is done by bcrypt.checkpw(password, hash) instead of hashing again. Using this approach the only options i can think of is to select the whole User table and travserse it on the server side. But i want to to the traversal on the db-side! How do i accomplish this using the bcrypt hashing method?
The whole way bcrypt works is that it gives you a value that combines the hashed password and salt into one value for you to store.
This means that you cannot recreate the hash from the password without the salt, which you do not have.
You need to select the user from the database via some user_id that you may have, and then use the bcrypt library to compare your password with the combined value that you have stored.
bcrypt.hashpw(password, hash_and_salt_value_from_db)
You can use the same function you used to create the "hash", but instead pass in your stored value. The function is smart enough to realise that it is a hash+salt and will extract and use the salt for you.
So you then want to check
if hash_and_salt_value_from_db == bcrypt.hashpw(password, hash_and_salt_value_from_db):
# tada, valid password
Shout if this doesn't make sense.
Modern security encryption assigns a unique salt (random string) to each user so that if some user, say Alice, signs up to you website and uses the password "password" then the hashed database entry she will be assigned is:
Hash("password" + "random_string_for_alice") = "HASH_VALUE:MD51000:random_string_for_alice"
Here the hash string includes the hashing algorithm (MD5)x1000 iterations and the salt used ("random_string_for_alice")
Now if you are just supplied a password - only a password and not a username - in order to find out whose (if any) username it belongs to you will have to look at each user's hashed password, extract the public salt and apply the iteration and then compare it. You will need to do this for each user in the database to find the answer.
And this is, of course, the point of modern password encryption recommendation..
Related
I'm making an application where there are user accounts in play.
All data of the user is encrypted using a key. This key is encrypted itself, using the hash of the user password. This means that when the user logs in with the correct password, the resulting hash will decrypt the key which can then be used to decrypt all other data of the user. The user password is the "gate" to all user data.
Forgetting their user password means losing their account. I want to implement a way to recover their account.
To recover their account, it needs to be possible to recover the decrypted key without storing it in decrypted form in the database and without encrypting it using a password. It needs to be recoverable using email recovery or something similar.
I haven't found a way to make this work and that's why I'm asking help. I don't need code (it's written in python though if you really want to); just pseudo-code about how one should go about implementing this is enough.
I need user_password plaintext using Django. I tried many ways to get plaintext in user_password. but It's not working. So, I analyzed how the Django user password is generated. it's using the make_password method in the Django core model. In this method generating the hashed code using( pbkdf2_sha256) algorthm. If any possible to decrypt the password.
Example:
pbkdf2_sha256$150000$O9hNDLwzBc7r$RzJPG76Vki36xEflUPKn37jYI3xRbbf6MTPrWbjFrgQ=
As you have already seen, Django uses hashing method like SHA256 in this case. Hashing mechanisms basically use lossy compression method, so there is no way to decrypt hashed messages as they are irreversible. Because it is not encryption and there is no backward method like decryption. It is safe to store password in the hashed form, as only creator of the password should know the original password and the backend system just compares the hashes.
This is normal situation for most backend frameworks. Because this is made for security reasons so far. Passwords are hashed and saved in the database so that even if the malicious user gets access to the database, he can't find usefull information there or it will be really hard to crack the hashes with some huge words dictionary.
I hope I didn't create a duplicate question.
I tried to look for already existing questions, but I didn't find anything.
I have successfully set up a database with username, salt and hashed password for logging in.
For checking the password, I compare the generated hash with the one of the database, see code below.
password_hashed_from_user = res[0][0]
salt = res[0][1]
key_generated = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), base64.b64decode(salt.encode('utf-8')), 100000, dklen=128)
key_encoded = base64.b64encode(key_generated).decode('utf-8')
if key_encoded != password_hashed_from_user:
logging.debug("Password was wrong:\n{}\n{}".format(key_encoded, password_hashed_from_user))
return "Username and/or password incorrect", False
The problem now is that I want the user to be able to act completely anonymously, which means I want the user to be able to use a generated token for identification, which cannot be traced back to his account.
Therefore I would need to store the token in a separate table, not correlated to the one with the credentials.
In order for the user to not be able to cheat and just ask the server for a new token every time he logs in (and therefore act as a new user), I wanted to compute the token based on the credentials.
So I figured, I could just have a separate salt and create a new hash based on the password (with the same method as in the code example).
Since the password itself is not stored on the server, this hash could not be generated without the password of the user itself.
This way, the generated token is always the same, as long as the salt doesn't change.
So I can make sure that a specific user is always identified as the same one, while the user can make sure that I cannot trace back his actions.
Background
The background is that I need to create a voting environment, where people have to register and identify themselves in order to prevent double voting, but the vote results, as well as the participation etc should not be traced back to the specific user.
As this is a project in my studies, I cannot just use existing frameworks/libraries.
Now my question:
Is it safe to store two separate hashes of the same password with different salts on the same server or would the duplication make it feasible to recreate the actual password? Both salts would be stored together, together with one of the hashes. The other hash would be in a separate, unrelated table.
I always struggled a bit with encryption on that level.
Is it safe to store two separate hashes of the same password with different salts on the same server or would the duplication make it feasible to recreate the actual password?
Yes, it is safe.
The basic idea behind that statement is that the salt "injects" sufficient uniqueness into the process that the password hash can work with to ensure that two different salts yield unrelated-looking hashes. A real-world example of this would be the worry of two different users having the same password (but different salts) - which also doesn't leak anything about the password and was one of the main motivations to introduce salts.
The more cryptographic argument is either you assume your hash acts like a random oracle - which yields unrelated random ouputs for unique inputs - in which case the uniqueness of the salt hides all output. Or you use a weaker assumption that your password hash is a randomness extractor combined with a pseudo-random function (not unreasonable for a cryptographic hash-based password-hash) with the key in the password input. In that case assuming the password is unknown and sufficiently random all unique salts will be mapped to strings that are indistinguishable from random output and therefore cannot yield any information about the output.
Alternatively you can also use Bellare, Ristenpart and Tessaro's definition for password hashing security which essentially says "breaking a password hash is as hard as guessing the password if said hash is good".
I'm implementing an api to an existing flask app, the login was created with Flask-User, however now I need to manually look up a user and match the password to authenticate.
The issue is I have no idea how to recreate the password hash to compare with the password Flask-User stored in the database.
Mostly because the Flask-User source at https://github.com/lingthio/Flask-User/blob/master/flask_user/passwords.py mentions a salt however from the database columns I have :
sqlite> pragma table_info(user);
0|id|INTEGER|1||1
1|username|VARCHAR(50)|1||0
2|password|VARCHAR(255)|1|''|0
3|reset_password_token|VARCHAR(100)|1|''|0
4|email|VARCHAR(255)|1||0
5|confirmed_at|DATETIME|0||0
6|is_active|BOOLEAN|1|'0'|0
7|first_name|VARCHAR(100)|1|''|0
8|last_name|VARCHAR(100)|1|''|0
There is no salt. So the question is how do I generate from a plaintext password a hash that I can compare to the hashes that Flask-User created.
Here's an inconsequential sample hash;
$2a$12$84F1dCPN1bVYEzPswDvgZu5ma1Xk5lNepvX/X9kKFYj8Q6Dy6j95q
Maybe try the user_manager.hash_password function. https://pythonhosted.org/Flask-User/api.html
I'm working on a python script that will need to connect to a postgreSQL server. What the best practice for the username and password? In this tutorial ZetCode is just using the username and password (if needed) in the code itself. Is this the right way or should there be some sort of hashed file to read from?
http://zetcode.com/db/postgresqlpythontutorial/
Store the username and password in a file, then restricting access to that file would be a good start.
Storing a hashed username or password won't work, because you cannot undo a hash function.
If you think that storing the username and password in plain text isn't secure enough in your situation, encrypt them. When the script starts, it asks for the passphrase. That passphrase is then hashed using PBKDF2 or scrypt. Use that hash as the key for encryption/decryption. See cryptographic right answers.
This does mean that your script needs operator input every time it starts!