杰瑞科技汇

Python加密salt如何生成与使用?

Of course! Let's break down how to perform password hashing in Python using the hashlib library with a salt. This is a critical security practice for storing user passwords.

Python加密salt如何生成与使用?-图1
(图片来源网络,侵删)

First, a crucial clarification: The command python .encrypt salt is not a valid Python command.

It looks like a mix of a command-line instruction and a concept. Let's break down what you likely mean and how to do it correctly.

  • python: This is the command to run the Python interpreter.
  • .encrypt: This is not a standard Python command. It might be a script you have named encrypt.py.
  • salt: This is a random value added to a password before hashing.

You probably want to write a Python script that takes a password and a salt, and securely "encrypts" (more accurately, hashes) it.


The Correct Terminology: Hashing vs. Encryption

It's very important to use the right term here.

Python加密salt如何生成与使用?-图2
(图片来源网络,侵删)
  • Encryption is a two-way process. You can encrypt data with a key and then decrypt it later with the same (or a different) key to get the original data back. (e.g., AES).
  • Hashing is a one-way process. You run data (like a password) through a hashing algorithm to produce a unique, fixed-size string of characters (the hash). You cannot reverse the process to get the original password back.

For storing passwords, we always use hashing, not encryption. If a database of password hashes is stolen, the attacker cannot "decrypt" them to get the passwords. They can only try to "crack" them by guessing passwords and hashing them to see if they match.

The Core Concept: Salt

A salt is a random piece of data that is used as an additional input to a one-way function that hashes data, a password or passphrase. Salts are used to safeguard passwords against pre-computed attacks, such as rainbow tables.

Why is salt essential? Without a salt, if two users have the same password, they will have the exact same hash in the database. An attacker who steals the database can instantly see which users have the same password. A salt ensures that even if two users have the same password, their hashes will be completely different because their salts are different.


Method 1: The Modern & Recommended Approach (PBKDF2)

For password hashing, you should use a slow, purpose-built hashing algorithm. PBKDF2 (Password-Based Key Derivation Function 2) is an excellent and widely recommended choice. It's designed to be slow, which makes brute-force attacks much more difficult.

Here is a complete, well-commented Python script.

File: hash_password.py

import hashlib
import os
import binascii # For converting bytes to hex string
def hash_password(password: str) -> tuple[str, str]:
    """
    Hashes a password using PBKDF2-HMAC-SHA256 with a randomly generated salt.
    Args:
        password: The plain-text password to hash.
    Returns:
        A tuple containing the salt and the hashed password, both as hex strings.
    """
    # 1. Generate a random salt. 16 bytes (128 bits) is a good size.
    # os.urandom is a cryptographically secure source of random bytes.
    salt = os.urandom(16)
    # 2. Hash the password with the salt.
    # We use PBKDF2-HMAC-SHA256.
    # - password.encode(): Convert the password string to bytes.
    # - salt: The salt we just generated.
    # - 100000: The number of iterations. Higher is slower and more secure.
    # - dklen=64: The length of the derived key in bytes. 64 bytes is good.
    hashed_password = hashlib.pbkdf2_hmac(
        'sha256',          # The hash digest algorithm to use
        password.encode(), # Convert the password to bytes
        salt,              # The salt
        100000,            # Number of iterations
        dklen=64           # The length of the hash
    )
    # 3. Return the salt and the hashed password as hex strings for easy storage.
    # Hex is a safe format to store in a database or file.
    return binascii.hexlify(salt).decode('utf-8'), binascii.hexlify(hashed_password).decode('utf-8')
def verify_password(stored_salt: str, stored_hash: str, provided_password: str) -> bool:
    """
    Verifies a password against a stored hash and salt.
    Args:
        stored_salt: The salt used for the original hash (hex string).
        stored_hash: The stored hash to compare against (hex string).
        provided_password: The password to check.
    Returns:
        True if the password is correct, False otherwise.
    """
    # 1. Convert the stored hex salt back to bytes.
    salt = binascii.unhexlify(stored_salt)
    # 2. Hash the provided password using the SAME salt and iterations.
    new_hash = hashlib.pbkdf2_hmac(
        'sha256',
        provided_password.encode(),
        salt,
        100000,
        dklen=64
    )
    # 3. Compare the new hash with the stored hash.
    # Use a constant-time comparison function to prevent timing attacks.
    return hmac.compare_digest(binascii.hexlify(new_hash).decode('utf-8'), stored_hash)
# --- Example Usage ---
if __name__ == "__main__":
    # A new user signs up
    my_password = "a-very-secret-password-123"
    salt, hashed_password = hash_password(my_password)
    print(f"Original Password: {my_password}")
    print(f"Generated Salt:    {salt}")
    print(f"Hashed Password:   {hashed_password}")
    print("-" * 30)
    # You would store these two values (salt and hashed_password) in your database
    # for this user.
    # --- Verification ---
    # The user tries to log in later
    login_attempt_1 = "a-very-secret-password-123"
    login_attempt_2 = "wrong-password"
    is_correct_password = verify_password(salt, hashed_password, login_attempt_1)
    print(f"Verifying '{login_attempt_1}': {'Success!' if is_correct_password else 'Failed!'}")
    is_wrong_password = verify_password(salt, hashed_password, login_attempt_2)
    print(f"Verifying '{login_attempt_2}': {'Success!' if is_wrong_password else 'Failed!'}")

How to Run This Script

  1. Save the code above as hash_password.py.

  2. Open your terminal or command prompt.

  3. Run the script using the python command:

    python hash_password.py

Expected Output:

Original Password: a-very-secret-password-123
Generated Salt:    a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
Hashed Password:   9e8d7c6b5a4b3c2d1e0f9a8b7c6d5e4f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5...
------------------------------
Verifying 'a-very-secret-password-123': Success!
Verifying 'wrong-password': Failed!

Note: The salt and hash will be different every time you run the script because os.urandom() generates a new random salt each time.


Method 2: The Even Better & Simpler Approach (Passlib)

For real-world applications, it's highly recommended to use a dedicated library like Passlib. It handles all the complexities for you, including choosing strong algorithms, managing salts, and providing a clean API.

First, you need to install it:

pip install passlib

Using Passlib (Argon2 is the modern standard)

Argon2 is the winner of the Password Hashing Competition and is considered the state-of-the-art for password hashing. Passlib makes it easy to use.

from passlib.hash import argon2
# --- Hashing a new password ---
password = "another-super-secret-password"
hashed_password = argon2.hash(password)
print(f"Original Password: {password}")
print(f"Argon2 Hash:       {hashed_password}")
print("-" * 30)
# --- Verifying a password ---
# The argon2.verify() function automatically extracts the salt and iterations
# from the stored hash string and performs the verification.
# Correct password
is_correct = argon2.verify(password, hashed_password)
print(f"Verifying correct password: {'Success!' if is_correct else 'Failed!'}")
# Incorrect password
is_wrong = argon2.verify("wrong-password", hashed_password)
print(f"Verifying wrong password: {'Success!' if is_wrong else 'Failed!'}")

Why is Passlib/Argon2 better?

  • Simplicity: The API is much cleaner. You don't manually handle salts.
  • State-of-the-Art: It defaults to the strongest available algorithm (Argon2).
  • Self-Contained: The salt and all parameters are stored within the
分享:
扫描分享到社交APP
上一篇
下一篇