Monday, April 4, 2022

Store Passwords Safely in Python (the bcrypt library)

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