Recover a salted and hashed password in python - python

I have managed to salt and hash password using this method:
import hashlib, uuid
salt = uuid.uuid4().hex
hashed_password = hashlib.sha512(password + salt).hexdigest()
How do I reverse this process to recover the actual password?
Update: You are supposed to take a password from the user, apply the same salt and hash method to their password, and then compare it with the originally salted/hashed password to see if they match. That makes perfect sense.

You don't. Hashing is a technique which is only one way. This is the whole point of hashing.
You never store raw passwords in order to protect your user if you got a leak of information in your DB.
If you want to implement some "password recover" procedure, you need to do as everyone do, send a email to the person with a temporary link to reset password on send a new one randomly generated.

Hashing is one way as in you can only encrypt (for example) a string and then compare the user provided hash with the one your app generates.
However, there is simple-crypt and it may be what you're looking for if you want "2 way" hashing.

Good question.
First off: never send users their passwords in plaintext!!
It's considered a bad security practice for a few reasons.
If anyone gets access to a user's email account (gmail, etc), then they have the password and can hijack the user account.
Second, hashing is a one-way form of encryption where you turn the password into gibberish. The big value in hashing is that the same password will always be turned into the same gibberish: every time. This means you can do password matching without ever storing the raw password. The reason you're supposed to hash a password and not do 2-way encryption like AES-256, is that 2-way encryption requires the creation, management, and securing of encryption keys which can be hard. Hashing is just easier and more secure for the vast majority of developers.
Instead of implementing password reset stuff by sending a user their password, you should instead send a user a link to a secure page where they can reset their password with a one-time token that expires after a certain amount of time.
This way, even if an attacker gets a hold of someone's email account (gmail, etc.) -- there's only a limited amount of time they can do damage.
There are a variety of ways to do this stuff yourself, but an easy approach to getting a one-time use token you don't have to store or manage is to offload user management to a microservice like Stormpath where it takes care of all the user management for you: password reset, password storage, user profiles, authentication, encryption, hashing, etc.
If you wanted to implement something like this in a Flask web app, for instance, you'd use the Flask-Stormpath library like so:
from flask import Flask
from flask.ext.stormpath import StormpathManager
app = Flask(__name__)
app.config['STORMPATH_ENABLE_FORGOT_PASSWORD'] = True
stormpath_manager = StormpathManager(app)
app.listen(3000)
NOTE: I work at Stormpath, but these rules apply regardless of what you're using and help make any application more secure.

Related

How can I synchronize wordpress users with firebase ones in python?

I would like that every time a user changes the password, it is also changed on firebase. The main problem is that the passwords taken from the wordpress database are hashed, while the auth.update_users command takes the raw password.
Obviously I'm not aware of the password in raw format...
What can I do?
i had try it:
...
users = auth.get_user_by_email('user1#gmail.com')
print('Successfully email fetched user data: {0}'.format(users.uid))
user = auth.update_user(
uid=users.uid,
password='$P$BOCNIc5Nw1e9fwm8HaLBChsd7eE4Hh1'
)
print('Sucessfully updated user: {0}'.format(user.uid))
There's nothing you can reasonably do here with the hash. The whole purpose of storing hashes (and hopefully salts) is to make it unfeasible to brute force revert password hashes to their cleartext password. If you could do that, so could any malicious user that gets access to the database of hashes.
If you want to send the cleartext password to two providers, you'll have to capture it at the source (so when the user enters it in the web app) and then send it to both providers.

Convert hashed password to string werkuzeug python

I am using Werkzeug for password hashing so that the passwords entered by users will be safe(atleast).
Lets say my application is as follows:
When a user gets logged in I will use check_password_hash and then login the user inside.
After the user is logged in, I want to show them their password.
The problem I am encountering:
How do I convert the hashed password back to string to show the user their password?
My code is as follows:
>>> import werkzeug.security as ws
>>> ws.generate_password_hash('abcdefg')
'pbkdf2:sha1:1000$fYAXLNA6$637528ae2fa195304c328d585e805b164f1c718f'
>>> ws._hash_internal('pbkdf2:sha1:1000', 'fYAXLNA6', 'abcdefg')
('637528ae2fa195304c328d585e805b164f1c718f', 'pbkdf2:sha1:1000')
Now how do I convert this '6375.....' back to 'abcdefg'?
I have access to database and the all the other stuff required. Basically I am the admin!
Note: I cannot use the password which user entered while logging in. I can only use the password from database.
After the user is logged in, I want to show them their password.
The whole purpose and reason of hashing a password is that you can never do this. Not you, not anyone else.
If someone has access or steals the database with the list of passwords, converting the hash back to the original password is really, really expensive. You will need a million years to break and reverse one single password.
We cannot get the original text back while using hashing. Generally all the passwords are stored as hash value, in order to make the passwords private (known only to the user). All the servers implement this. If you want to get the password back then you should use symmetric key cryptography. Where a secret key will be shared between the clients and the server (But it is a very bad practice) It better that you go with hashing.

How to implement "Incorrect username/password" hint for a webservice using Flask HTTP Auth?

I have a client app that interacts with a web service to retrieve account information. There's a requirement that the user is notified if they mistyped the username/password. I'm modifying the web service to return something to my client to provide a hint to the user that there's an error in input.
How do I correctly implement the "username/password" not found for a web service using Python?
Do I tell the user that the username exists, but the password is incorrect?
Do I tell the user that there is no such username, but the password matched something?
Do I show a generic username/password combination is not found?
Do I use different status codes for different situations or provide a JSON payload with the error?
here's my code so far:
from flask.ext.httpauth import HTTPBasicAuth
accounts = [
["user0", "password0"],
["user1", "password1"],
]
#app.route('/accountlist')
#auth.login_required
def accountlist()
username = auth.username();
if ... : #check if accounts does not have the given username
#notify the sender that there is no such username
return Response('Not Authorized', 401, {'WWW-Authenticate': 'Basic'})
else:
#proceed to check password and retrieve/return account information
Do I show a generic username/password combination is not found?
Yes. Why do you think this is "generic"? Because it is the standard. This is the correct way because than a hacker can't go phishing for usernames.
Do I tell the user that the username exists, but the password is incorrect?
No, letting the user know that the username is correct is a user enumeration vulnerability. You are letting an attacker know which usernames are valid allowing them to narrow their target range. This would be useful if they later decided to try a brute force attack as they already know the usernames are correct and now they only need a working password.
Do I tell the user that there is no such username, but the password matched something?
Definitely not. This would mean that the attacker now had a valid password and could use any other username enumeration vulnerability on your site in order to try and find a valid username. Another common username enumeration location is the forgotten password form - many sites report back that there is no such username allowing an attacker to refine their list. Alternatively, they could use this password and brute force a username from it which may be a much easier job as usernames shouldn't benefit from being complex.
As an aside to this, you should be storing your passwords salted and hashed using a secure, slow algorithm such as bcrypt. This should mean it is not possible for you to practically check to see if any password matches the one entered.
Do I show a generic username/password combination is not found?
Yes!
Do I use different status codes for different situations or provide a JSON payload with the error?
Your JSON could return true or false to let the calling JavaScript know whether authentication was successful. If you ever develop any brute force protection, this should be accomplished by introducing a delay in the response rather than hard locking accounts. Hard locking accounts leads to a DoS attack as an attacker can lock out a valid account by repeatedly using the wrong password on purpose. For this reason, only a true/false response is really needed to let the user know if they were successful. Even if the account was hard locked, I would return false but include in the message that the user should contact technical support if they believe they should have access with the password provided.
You don't mention what kind of data you're serving but if you're working in financial or health care data: make it so either the user can log in or they cannot, you shouldn't endeavor to give them any information as to why.
If you want you can tell them that the username is incorrect but you cannot suggest other usernames. And, of course, you cannot give any information about what might be wrong with the password, just tell them that it's incorrect.
About the code you presented, I realize you didn't really ask for coding advice, still, I do tons of code reviews and consistently see the same issues over-and-over with these roll-your-own authentication schemes. If your code is ever audited the auditor will likely find the following issues:
You must never hardcode passwords.
You must never persist a password in cleartext, always use an irreversible hash (SHA-1 or greater) when a password is received and only work with the hash value
Your applicatoon should 'fail-closed', meaning set up the accountList() function to return a 'not authorized' prior to the if statement and prior to calling any functions that would throw an exception (like a database access). Make the auth check in the if statemnt. That way if something fails in the things that the if statement calls (say an exception in data access or file i/o) the user fails to log in.

How to create a user login section in Python with Tkinter module

I'm working on a small uni project where I have a program for a single user in Python using the tkinter module. I want create a screen where they will be required to enter their password. I'm not sure how to do this and where would I store the password?
I have no experience in database but I've heard of MD5 & SHA256 and I was thinking of writing the hashed or encrypted password to a text file and then reading it but I am not sure if this is safe.
The password functionality is to prevent others from looking at the users' personal diary entries.
This answer takes the simplest route in achieving a measure of security. #J.F.Sebastian points out in comments that you can definitely explore more robust security procedures with greater encryption, but this really depends on your needs
If your goal is just to experiment and create a proof-of-concept login system, you can just go with the encryption + flat file approach. For storing a password, you probably only need SHA1 since what you are encrypting is a variation of the password, and not sensitive data itself. What I mean is that you don't care about the data itself. You only care about comparing encryption results...
First you would pick a secret character set as a "salt". Unfortunately you are using an uncompiled language, so your salt will probably live within your program. But at least the password files by themselves are not useable. ("salt" is being used here as your only secret value. In a more secure approach, the secret would be a separate key used outside of the hashing of the password+salt)
import hashlib
salt = "-WOu#p.Za,>W+6&`A63/"
user_password = "password"
sha1 = hashlib.sha1()
sha1.update(user_password + salt)
encrypted = sha1.hexdigest()
print encrypted
# 476dc4076d1c7eb43152b78e9dc20d892f660f24
You can store that encrypted sha1 value to a file. Its of no use to anyone without the secret salt value. All you will do is use this value to compare against the future sha1 value when a user authenticates
test_sha1 = hashlib.sha1(raw_input("Enter password: ") + salt).hexdigest()
# Enter password: password
print encrypted == test_sha1
# True
You never actually know their password. You only know the sha1 value derived from it plus the salt. Think of it like two guards each needing to provide a key, turned simultaneously, to open the vault.
Otherwise.... you can store this in a database, along with the salt value. The procedure would still be the same but you move the salt to a more secure location that requres auth to even query it. No matter what, your salt secret is the most prized possession.
Addressing the SHA256... Greater encryption algorithms are needed for the act of storing the real data in a tangible format that needs protection (or when creating a slower hashing process for your passwords to make brute force cracking take longer to accomplish). For instance, if you decided to store a users private diary entries, you might encrypt against their password, and only store this encrypted format either on disk or in a database. When the user authenticates, you can deliver to them the decrypted data by way of their password. You never store the password, so even you as the author of the software can't access their data without their original password.
Again, as #J.F.Sebastian points out, the more robust approach would be using a bcrypt library:
http://www.mindrot.org/projects/py-bcrypt/

Is there anything wrong with this password reset procedure?

Is there anything wrong with this procedure?
Enter in username and email in a reset form.
Flask creates a really long random string and stores it into the session under "reset_code". Session will also have a key for "reset_pw_username"
Flask sends an email with a link to the path /password_reset/reset_pw_username/reset_code
That link displays a form where the customer can reset the password if the session reset code matches the session reset_code item. Otherwise it bombs out.
The session will expire the reset code after an hour.
If I can enter a username and email address, then I can get a reset token for any user of your service emailed to me. Maybe you should check that the email address is one that actually belongs to the user whose password is going to be reset.
You must ensure that username and email entered match one of the accounts (or use emails as username in the first place).
From a usability perspective, this won't work if the browser that displays the link contained in the email is not the same as the one initially used.
Apart from that, you should pay special attention to the randomness (not so much the length) of the reset_code. It should be cryptographically random (i.e. os.urandom) so that an attacker cannot simply guess it. random.random and derived methods are not suitable.
As Jean-Paul pointed out, asking for both username and e-mail requires checking whether they both match the same user. Hence it is more common to ask for either username or e-mail, verifying they are in your database, and sending recovery link to appropriate address.
Storing the recovery token in session data will likely be cumbersome for some users, as phihag described. Such tokens are usually stored in regular database. Note, however, that they are password-equivalent: once obtained, they can be freely exchanged for a password. Because of that, they need to salted & hashed (in the same secure manner that is applied to passwords themselves) before storing in the database. This also means that your recovery handler must salt & hash the incoming token before searching for it in your database.
The best solution is use email address as username,then user just have to remember his email address.And you just only have to validate user's email address.

Categories

Resources