Password Hashing with bcrypt in Python

Updated on: August 20, 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

    TOML configuration in a Python project
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Python tomllib: Read TOML Files

    Learn how to read TOML with Python tomllib, validate settings, handle parse errors, and organize projects with pyproject.toml.

    Ler mais

    Tempo de leitura: 6 minutos
    24/07/2026
    Developer monitoring structured Python application logs
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Observability in Python with structlog

    Build practical Python observability with structlog, JSON events, request context, tests, performance controls, and deployment guidance.

    Ler mais

    Tempo de leitura: 5 minutos
    24/07/2026
    Secure Python application configuration with Pydantic Settings
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Pydantic Settings for Safe Config

    Learn how to validate environment variables, manage secrets, and organize Python application settings with Pydantic Settings.

    Ler mais

    Tempo de leitura: 5 minutos
    23/07/2026
    Desenvolvedor programando em Python com Ruff para lint e formatação
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Ruff: Lint and Format Python Code

    Learn Ruff for Python linting, formatting, automatic fixes, pyproject.toml, VS Code and CI with a practical project configuration.

    Ler mais

    Tempo de leitura: 9 minutos
    22/07/2026
    2 balões de comentários em um fundo laranja
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Python Comments: Syntax and Best Practices

    Learn Python comments with single-line and inline examples, block explanations, TODO notes, docstrings, security and performance context, review standards, and

    Ler mais

    Tempo de leitura: 6 minutos
    10/07/2026
    Pessoa programando em um notebook, vista de trás, com código desfocado exibido na tela em um fundo escuro
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Python Docstrings: Functions, Classes, and Modules

    Learn Python docstrings for functions, classes, methods, modules, parameters, returns, exceptions, examples, pydoc, conventions, and documentation tools.

    Ler mais

    Tempo de leitura: 6 minutos
    10/07/2026