Store Passwords Safely in Python (the bcrypt library)
When storing passwords, one of
the greatest risks is that someone may steal the database and be able to
decrypt them. To avoid this, you could hash the passwords before storing them. We
need to install bcrpyt using pip: pip
install bcrypt
It is good practice (although not required) to create a new virtual environment for this project. If you want to learn more about this, check How to Create and Manage Virtual Environments in Python
What is Password Hashing?
A hashing function is a function that takes a string of bytes, and “transforms” it to another string of bytes, from which it is impossible to determine the initial string. Furthermore, there aren’t two different inputs that give the same output. This means that if we store the hashed password, even if someone stole the database they would not be able to determine what the plain text passwords are.
Suppose a user has registered with the password "HelloWorld". To execute the login, we check if the password entered is the same as the stored one. To do so, we hash the password used for the login, and check if this hash corresponds to the stored one. Since by the definition there aren’t two different inputs that give the same output, the two hashes will be equal only if the password entered by the user is the same as the one used during registration.
The only weakness is that if the password is short, an attacker may try to hash all possible passwords until he finds the correct one. However, this is unlikely if the password is long enough since there are too many combinations. But how to make sure that the password is long? Usually, before hashing a password we will add a salt, i.e. a random sequence of characters. In this way, we know that even if the user uses a short password, it will still be secure.
Testing the Code
Here is the complete code of our PasswordDatabase:
import bcrypt
class PasswordDatabase:
def
__init__(self):
self.data = dict()
def register(self,
user, password):
if user
in self.data:
return
False
hashed =
bcrypt.hashpw(password, bcrypt.gensalt(10))
self.data[user] = hashed
return
True
def
login(self, user, password):
if user
not in self.data:
return
False
pwd_bytes = password.encode("utf-8")
return
bcrypt.checkpw(pwd_bytes, self.data[user])
# Driver
code:
db = PasswordDatabase()
print("Registering users")
print(db.register("John",
b"password"))
print(db.register("Seth", b"HelloWorld"))
print(db.register("John",
b"myname")) # False - John already exists
print("Logging in users")
print(db.login("Abc",
"password"))
print(db.login("John", "pwd"))
print(db.login("John", "password")) # True - matches password
Useful links:
Python bcrypt tutorial shows how to hash passwords in Python with the bcrypt library… zetcode.com
Hashing Passwords In Python: Bcrypt Tutorial with Examples | HackerNoon
No comments:
Post a Comment