Amazing Python Package Showcase (2) – PassLib

Amazing Python Package Introduction Series: PassLib

In this second article of the “Introducing Amazing Python Packages” series, we delve into PassLib, a comprehensive password hashing library for Python. With an array of secure password hashing algorithms and a straightforward API, PassLib makes it easy to implement robust password security in your applications.

What is PassLib?

PassLib is a password hashing library that provides a suite of secure password hashing algorithms. It supports a wide range of hashing schemes, from modern and highly secure ones like bcrypt and scrypt to traditional ones like md5 and sha1, making it a versatile tool for any application requiring password security.

Key Features

  • Multiple Hashing SchemesPassLib supports various hashing algorithms, allowing developers to choose the one that best fits their security needs.
  • Ease of Use: The library offers a simple API for hashing and verifying passwords, making it accessible even for those new to password security.
  • ConfigurablePassLib allows for detailed configuration of its hashing algorithms, including cost parameters and other options.
  • Compatibility: The library is designed to be compatible with existing hashes, ensuring that transitioning to PassLib from other libraries is seamless.

Installation

Create an environment in your project using virtualenv:

(Regarding virtualenv, you can refer Amazing Python Package Showcase (1) – virtualenv)

# create an new environment
dynotes@P2021:~/projects/python$ virtualenv passlib
created virtual environment CPython3.10.12.final.0-64 in 434ms
  creator CPython3Posix(dest=/home/dynotes/projects/python/passlib, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/dynotes/.local/share/virtualenv)
    added seed packages: pip==24.1, setuptools==70.1.0, wheel==0.43.0
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

# activate it
dynotes@P2021:~/projects/python$ source ./passlib/bin/activate
(passlib) dynotes@P2021:~/projects/python$cd pa

Then install PassLib using pip:

(passlib) dynotes@P2021:~/projects/python/passlib$ pip install passlib
Collecting passlib
  Downloading passlib-1.7.4-py2.py3-none-any.whl.metadata (1.7 kB)
Downloading passlib-1.7.4-py2.py3-none-any.whl (525 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 525.6/525.6 kB 4.2 MB/s eta 0:00:00
Installing collected packages: passlib
Successfully installed passlib-1.7.4

Basic Usage

Here’s a simple example of how to hash and verify a password using PassLib

from passlib.context import CryptContext

# Define a context with default settings
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

# Hash a password
hashed_password = pwd_context.hash("mysecretpassword")

# Verify the password
is_valid = pwd_context.verify("mysecretpassword", hashed_password)

print("Hashed Password:", hashed_password)
print("Password is valid:", is_valid)

Run it

(passlib) dynotes@P2021:$ python passlib_example1.py
Hashed Password: $2b$12$XkBuLIB9kdVfj1cL7JET7eor4TK8G/1OcitMSWVwv3A0yr9LfArh.
Password is valid: True
(passlib) dynotes@P2021:$

Advanced Configuration

PassLib allows you to customize its behavior extensively. You can specify different hashing schemes, set parameters for these schemes, and even define policies for deprecated algorithms.

from passlib.context import CryptContext

# Define a more complex context
pwd_context = CryptContext(
    schemes=["pbkdf2_sha256", "argon2", "bcrypt"],
    default="pbkdf2_sha256",
    pbkdf2_sha256__default_rounds=30000,
    bcrypt__rounds=13,
    argon2__time_cost=4,
    argon2__memory_cost=102400,
    argon2__parallelism=8,
)

# Hash and verify using the context
hashed_password = pwd_context.hash("mysecretpassword")
is_valid = pwd_context.verify("mysecretpassword", hashed_password)

print("Hashed Password:", hashed_password)
print("Password is valid:", is_valid)
Run it

(passlib) dynotes@P2021:$ python passlib_example2.py
Hashed Password: $pbkdf2-sha256$30000$a.197x1jjJGyVkppbS1lrA$hANpfK7qfTP0uxEvqZmy0BqrmnH/fEFQH3wyU0pfuyY
Password is valid: True
(passlib) dynotes@P2021:$
Migration and Integration
PassLib is designed to work with a variety of systems and existing password hashes. You can migrate from older, less secure hashing algorithms to more secure ones supported by PassLib without disrupting user experience.

from passlib.context import CryptContext

# Example context with migration support
pwd_context = CryptContext(
    schemes=["bcrypt", "sha256_crypt", "md5_crypt"],
    default="bcrypt",
    sha256_crypt__deprecated="auto",
    md5_crypt__deprecated="auto",
)

# Hashing and verifying with migration
hashed_password = pwd_context.hash("mysecretpassword")
is_valid = pwd_context.verify("mysecretpassword", hashed_password)

print("Hashed Password:", hashed_password)
print("Password is valid:", is_valid)
Run it

(passlib) dynotes@P2021:$ python passlib_example3.py
Hashed Password: $2b$12$QcrAhdQKFWXql21FgIWApupvHzQjWfcNzO73Woxk2alVmQdIYMKI2
Password is valid: True
(passlib) dynotes@P2021:$
Practical Example: User Registration and Login System
Let’s create a simple user registration and login system using Python and PassLib. We’ll store user information, including hashed passwords, in a dictionary for simplicity.

from passlib.context import CryptContext

# Define a context with bcrypt as the default hashing scheme
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

# Dictionary to store user data
users_db = {}

def register_user(username, password):
    if username in users_db:
        print("User already exists!")
        return False

    # Hash the password
    hashed_password = pwd_context.hash(password)
    
    # Store the user with the hashed password
    users_db[username] = hashed_password
    print(f"User {username} registered successfully.")
    return True

def login_user(username, password):
    if username not in users_db:
        print("User not found!")
        return False

    # Retrieve the stored hashed password
    hashed_password = users_db[username]

    # Verify the provided password against the stored hash
    if pwd_context.verify(password, hashed_password):
        print(f"User {username} logged in successfully.")
        return True
    else:
        print("Invalid password!")
        return False

# Testing the system
register_user("john_doe", "mysecretpassword")
login_user("john_doe", "mysecretpassword")
login_user("john_doe", "wrongpassword")
Run it

(passlib) dynotes@P2021:$ python passlib_userlogin.py
User john_doe registered successfully.
User john_doe logged in successfully.
Invalid password!
(passlib) dynotes@P2021:$

In our next article, we will continue to explore more amazing Python packages that can enhance your development workflow. Stay tuned!

You Might Also Like

Leave a Reply