Python Password Hashing with bcrypt

Published on: June 3, 2026
Reading time: 4 minutes
Criação de hashes seguros para senhas usando Python

Ensuring user data security is one of the most critical responsibilities of any software developer. When it comes to protecting credentials, the golden rule is to never store passwords in plain text. Instead, we use Python password hashing to transform sensitive information into an unrecognizable, irreversible sequence of characters. If a database is breached, the attacker finds only complex cryptographic codes instead of real passwords. This article teaches you how to implement a robust security system using best practices.

What is a hash and why is it essential?

A hash is the output of an algorithm that transforms any block of data into a fixed-length sequence. Unlike regular encryption, hashing is a one-way operation: you cannot “decrypt” a hash to get the original password back. When a user logs in, the system hashes the entered password and compares it to the stored hash. According to OWASP, secure password storage is the first line of defense against large-scale data breaches.

Choosing the right library

Python’s built-in hashlib with MD5 or SHA-256 is not recommended for passwords. These algorithms are too fast, allowing attackers to test millions of combinations per second. Use algorithms designed to be intentionally slow, like bcrypt or Argon2. Bcrypt is an industry standard that automatically handles the “salt” (random characters added to the password before hashing, ensuring two users with the same password get different hashes). For generating cryptographically secure tokens, see also Python secrets module.

Bash
pip install bcrypt

Generating a secure hash

Python
import bcrypt

Verifying a password

Python
def verify_password(entered_password, stored_hash):

Production-ready function with configurable cost

The rounds parameter in gensalt() controls the computational cost. Higher values make hashing slower, which is good for security but has a performance cost. The default is 12. OWASP recommends tuning this so hashing takes around 1 second on your server. For a complete project applying these concepts, check out building a password manager in Python.

Python
import bcrypt

MD5/SHA-256 vs bcrypt: comparison

AlgorithmSpeedSaltRecommended for passwords
MD5Very fastNoNo
SHA-256FastNoNo
bcryptConfigurable (slow)Yes (auto)Yes
Argon2Configurable (slow)Yes (auto)Yes (preferred)

Frequently asked questions

Can I recover the original password from a bcrypt hash?

No. Bcrypt is a one-way function by design. There is no decryption. The only way to verify a password is to hash the new input and compare it to the stored hash using bcrypt.checkpw().

Should I use bcrypt or Argon2 in 2026?

Both are good choices. Argon2 (via the argon2-cffi library) is the current OWASP recommendation as it won the Password Hashing Competition and is more resistant to GPU-based attacks.

Does each call to gensalt() produce a different hash?

Yes. Every time you call bcrypt.gensalt() a new random salt is generated, so the same password produces a different hash each time. This is intentional. The salt is embedded in the hash string, so bcrypt.checkpw() can always verify correctly.

Password hashing is a non-negotiable security practice. Implementing bcrypt in Python is straightforward and protects your users against the most common types of credential attacks.

Share:

Facebook
WhatsApp
Twitter
LinkedIn

Article content

    Related articles

    Uso de dataclasses para simplificar classes em Python
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Python Dataclasses: Clean Data Classes Easily

    Learn how Python dataclasses work: auto-generate __init__, __repr__, __eq__, use default values, field(), frozen=True, __post_init__, and asdict/astuple.

    Ler mais

    Tempo de leitura: 4 minutos
    03/06/2026
    Entendendo como o GIL afeta performance em Python
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Python GIL: What It Is and How It Affects Code

    Learn what Python's GIL is, why it exists, how it limits multithreading, and when to use multiprocessing to achieve true

    Ler mais

    Tempo de leitura: 6 minutos
    03/06/2026
    Medição de tempo de execução de código Python com timeit
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Measure Python Code Speed with timeit

    Learn how to measure Python code execution time with timeit: command line, setup parameter, function references, repeat(), and benchmarking best

    Ler mais

    Tempo de leitura: 4 minutos
    30/05/2026
    Como resolver erros com variáveis de ambiente usando python-dotenv
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Fix .env Errors in Python with python-dotenv

    Learn how to fix .env variable errors in Python using python-dotenv, load_dotenv, os.getenv, default values, find_dotenv, and API key security

    Ler mais

    Tempo de leitura: 4 minutos
    29/05/2026
    Leitura de variáveis de ambiente em projetos Python
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Read Environment Variables in Python Safely

    Learn how to read environment variables in Python safely with os.getenv, .env files, python-dotenv, validation, secrets, and deployment tips.

    Ler mais

    Tempo de leitura: 9 minutos
    21/05/2026
    Introdução ao uso de type hints em Python
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Python Type Hints: Write Cleaner Code

    Learn Python type hints with practical examples, function annotations, generics, Union, Optional, mypy, and best practices for cleaner code.

    Ler mais

    Tempo de leitura: 9 minutos
    21/05/2026