← Back to Blog

Hashing in Python: From hashlib to Modern Password Hashing

March 22, 2026 3 min read By CodeTidy Team

The Dark Side of Hashing: Why MD5 and SHA are Not Your Friends

We've all been there - trying to hash a password or a string in Python, only to realize that the built-in hashlib library is not as secure as we thought. In fact, using MD5 or SHA for password hashing is a common mistake that can put our users' data at risk.

Table of Contents

  • The Basics of Hashing in Python
  • The Trouble with MD5 and SHA
  • Introducing HMAC: A Safer Alternative
  • Modern Password Hashing with Bcrypt and Argon2
  • Best Practices for Hashing in Python
  • Key Takeaways
  • FAQ

The Basics of Hashing in Python

Hashing is a one-way process that takes input data of any size and produces a fixed-size string of characters, known as a message digest. Python's hashlib library provides an implementation of various hashing algorithms, including MD5 and SHA.

Here's an example of how to use hashlib to hash a string:

import hashlib

string = "Hello, World!"
hashed_string = hashlib.md5(string.encode()).hexdigest()
print(hashed_string)

The Trouble with MD5 and SHA

While hashlib is easy to use, it's not suitable for password hashing. MD5 and SHA are designed to be fast and efficient, but this comes at the cost of security. They are vulnerable to collisions, which means that two different inputs can produce the same output hash.

Moreover, MD5 and SHA are not designed to be slow, which makes them susceptible to brute-force attacks. An attacker can use a powerful computer to try millions of combinations per second, making it easy to crack passwords.

Introducing HMAC: A Safer Alternative

HMAC (Hash-based Message Authentication Code) is a more secure alternative to hashlib. It uses a secret key to create a message digest, making it more resistant to collisions and brute-force attacks.

Here's an example of how to use HMAC:

import hmac
import hashlib

secret_key = "my_secret_key"
message = "Hello, World!"
hashed_message = hmac.new(secret_key.encode(), message.encode(), hashlib.sha256).hexdigest()
print(hashed_message)

Modern Password Hashing with Bcrypt and Argon2

For password hashing, we recommend using Bcrypt or Argon2, which are designed to be slow and computationally expensive. This makes them more resistant to brute-force attacks.

Bcrypt is a popular choice for password hashing, and it's widely used in many applications. Here's an example of how to use Bcrypt:

import bcrypt

password = "my_password"
hashed_password = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
print(hashed_password)

Argon2 is another popular choice, and it's designed to be more secure than Bcrypt. Here's an example of how to use Argon2:

import argon2

password = "my_password"
hashed_password = argon2.hash_password(password.encode())
print(hashed_password)

Best Practices for Hashing in Python

When hashing in Python, we recommend the following best practices:

  • Use a secure hashing algorithm like Bcrypt or Argon2 for password hashing.
  • Use a secret key with HMAC for message authentication.
  • Never use MD5 or SHA for password hashing.
  • Always use a salt when hashing passwords.

Key Takeaways

  • MD5 and SHA are not suitable for password hashing.
  • Use Bcrypt or Argon2 for password hashing.
  • Use HMAC with a secret key for message authentication.
  • Always use a salt when hashing passwords.

FAQ

Q: Why is MD5 not suitable for password hashing?

A: MD5 is vulnerable to collisions and brute-force attacks, making it insecure for password hashing.

Q: What is the difference between Bcrypt and Argon2?

A: Bcrypt and Argon2 are both designed for password hashing, but Argon2 is considered more secure than Bcrypt.

Q: How do I use a salt when hashing passwords?

A: A salt is a random value added to the password before hashing. You can use a library like Bcrypt or Argon2 to generate a salt and hash the password.

AI agent tools available. The CodeTidy MCP Server gives Claude, Cursor, and other AI agents access to 60+ developer tools. One command: npx @codetidy/mcp