Bcrypt Cost Factor: Exponential Scaling and Input Limits
Learn how the bcrypt cost factor works, including its exponential growth, the seventy-two byte input limit, and how to manage hash security upgrades safely.
The cost factor in bcrypt is not a linear multiplier. It is an exponent. The number of iterations performed by the algorithm is two to the power of the cost factor. If you set the cost to ten, the algorithm runs one thousand and twenty four rounds. Increasing that number to eleven does not add one round; it doubles the work to two thousand and forty eight rounds.
This exponential growth is a deliberate design choice. It ensures that as hardware becomes faster, you can increase the cost factor by small increments to keep the computation time constant. The goal is to make the process slow enough to frustrate an attacker using a cluster of GPUs, but fast enough that a single user does not notice a delay of a few hundred milliseconds during a login attempt. You are essentially trading CPU cycles for security.
The hidden limits
There are two specific details in the bcrypt specification that often lead to confusion. The first is the input limit. Bcrypt ignores any characters in the password string beyond the seventy second byte. If you provide a password that is one hundred characters long, the algorithm only considers the first seventy two. The remaining twenty eight characters are discarded entirely. This means a user could change the end of a very long password and still successfully authenticate, provided the first seventy two bytes remain identical. It is an odd relic of the design that you must account for if you allow excessively long passwords.
The second detail concerns where the cost factor is stored. You do not need to maintain a separate database column to track which cost was used for which user. The cost is encoded directly into the resulting hash string. When the library reads the hash from your database, it extracts the cost factor from the prefix before beginning the verification process. This allows different users to have hashes created with different costs simultaneously without breaking the authentication flow.
Managing upgrades
Because the cost factor is baked into the hash string, you cannot simply update a global configuration setting and expect existing passwords to become more secure. A hash created with a cost of ten will always be a cost ten hash. To increase the security of an old password, you must recompute the hash using the new cost factor.
You cannot do this in a bulk database operation because you do not possess the plaintext passwords. You only have access to the plaintext for a fleeting moment when the user provides it during a login attempt. The correct workflow is to verify the password against the existing hash first. Once the identity is confirmed, you check if the cost factor stored in that hash matches your current security requirement.
If the hash uses an outdated cost of ten but your new standard is twelve, you immediately rehash the plaintext password using the higher cost and overwrite the old entry in your database. This migrates your users to the stronger security setting organically over time. You avoid a mass password reset while ensuring that every active account eventually meets your current requirements. It is a quiet transition that happens in the background of a standard session start.
Try it: bcrypt generator and verifier
Sources
Every link below is checked before this page is published.