You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Spring BCrypt哈希生成固定密钥:探寻哈希公共固定部分

Answer to Your BCrypt Key Derivation Question

Great question—let’s break this down step by step, since BCrypt’s design can be tricky if you’re trying to use it beyond basic password authentication.

First: How BCrypt Hashes Work

Every BCrypt hash looks something like this example:
$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy

Let’s split it into its components:

  • $2a$: The BCrypt algorithm version
  • 10$: The cost factor (controls how computationally expensive the hash is)
  • N9qo8uLOickgx2ZMRZoMye: A randomly generated 16-byte salt (encoded as 22 characters)
  • IjZAgcfl7p92ldGxad68LJZdL17lhWy: The actual password hash (24 bytes, encoded as 31 characters)

The reason the same password produces different BCrypt hashes every time is that the salt is randomly generated for each hash operation. This is a critical security feature—it prevents rainbow table attacks.

Do Same-Password BCrypt Hashes Have a Fixed Common Part?

Short answer: No, not one that’s tied to the password itself.

If you always use the same cost factor, the prefix (like $2a$10$) will be identical across all hashes for that cost. But this prefix has nothing to do with the password—it’s just metadata about the BCrypt configuration. The rest of the hash (salt + password hash) is unique for every generation, even for the same password. There’s no shared, password-specific segment you can extract to generate a fixed key.

What’s the Correct Approach for Your Use Case?

Your goal is to generate a fixed key from a password, even though BCrypt produces variable hashes. Here are the best options:

1. Derive the key directly from the password (not the BCrypt hash)

Use a Key Derivation Function (KDF) designed for this purpose—like PBKDF2-HMAC-SHA256, Argon2id, or scrypt. Unlike BCrypt (which uses a random salt by default), you’ll use a fixed salt (either an application-wide salt, or a user-specific fixed salt like their ID concatenated with a secret) to ensure the same password always produces the same key.

Example pseudocode:

# When setting up the user
password = user_input_password()
bcrypt_hash = bcrypt.hashpw(password, bcrypt.gensalt())  # Random salt for auth
fixed_salt = b"your_app_secret_fixed_salt_here"  # Store this securely, not in plaintext!
fixed_key = pbkdf2_hmac(
    hash_name='sha256',
    password=password,
    salt=fixed_salt,
    iterations=100000
)
store(bcrypt_hash, encrypt(fixed_key))  # Encrypt the key before storing

# When the user logs in later
input_password = user_login_password()
stored_bcrypt_hash = get_stored_hash(user_id)
if bcrypt.checkpw(input_password, stored_bcrypt_hash):
    # Password is valid, derive the fixed key
    fixed_salt = b"your_app_secret_fixed_salt_here"
    fixed_key = pbkdf2_hmac(
        hash_name='sha256',
        password=input_password,
        salt=fixed_salt,
        iterations=100000
    )
    # Use fixed_key for your intended purpose

2. Avoid trying to reuse BCrypt hashes for key derivation

You might be tempted to take a BCrypt hash and run it through a deterministic hash (like SHA-256) to get a fixed key, but this won’t work for your needs—each BCrypt hash of the same password is unique, so you’d end up with a different key every time. This defeats the point of having a fixed key.

Critical Security Notes

  • Never expose the fixed salt you use for key derivation. If an attacker gets this salt, they can brute-force passwords to generate the corresponding keys.
  • Always encrypt the fixed key before storing it in your database—don’t store it in plaintext.
  • Prefer modern KDFs like Argon2id over PBKDF2; it’s more resistant to GPU-based attacks.

内容的提问来源于stack exchange,提问作者Chung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:34:47