Skip to content

Invalid salt when setting salt manually in versions 4.0+ #1004

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jose-lpa opened this issue Mar 12, 2025 · 1 comment
Open

Invalid salt when setting salt manually in versions 4.0+ #1004

jose-lpa opened this issue Mar 12, 2025 · 1 comment

Comments

@jose-lpa
Copy link

Sorry if this is not the correct channel to ask this question, but I cannot find any answers to it.

This code works fine in any version less than 4.0.0:

import bcrypt

# A predefined salt in the correct format (with a valid 22-character base64 encoded salt)
# Example format: "$2b$12$abcdefghijklmnopqrstuvwxz"
predefined_salt = b"$2b$12$abcdefghijklmnopqrstuvwxz"  # 22 characters after the cost

# Hash the password using the predefined salt
password = b"my_secure_password"
hashed = bcrypt.hashpw(password, predefined_salt)

print(f"Hashed password: {hashed}")

Will invariably print this, because the salt has been set manually:

Hashed password: b'$2b$12$abcdefghijklmnopqrstuuWPjIcbaogT1FbIphDv1Lk3mqxnJWwO2'

However, it doesn't seem to work anymore when I upgrade from versions 3.x to 4.x. The line

hashed = bcrypt.hashpw(password, predefined_salt)

returns a ValueError: invalid salt exception.

I wonder if this is totally intentional, and therefore is not possible to set a static salt anymore?

My problem, and use case, is that I have to migrate a production codebase which DB has all the user passwords stored with a specific predefined salt that is stored as a secret in the infra. So I can definitely not use the, otherwise absolutely sensible, bcrypt.gensalt() function.

Thanks.

@alex
Copy link
Member

alex commented Apr 27, 2025

The first 22 digits of the salt need to be, by themselves, valid base64 which decode to 16 bytes. Other than that, passing your own salts is allowable: https://github.com/pyca/bcrypt/blob/main/src/_bcrypt/src/lib.rs#L83-L122

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants