Skip to content

Spring Security Bcrypt with strength/log rounds = 31 results in 'Bad number of rounds' error although 31 should be ok #11470

@sabinewinklerboi

Description

@sabinewinklerboi

Describe the bug:
I implement a webapp using Spring Boot and Spring Security. Passwords of my users are stored in my DB after encoding with Bcrypt (BCryptVersion $2a).
I use Bcrypt of Spring Security with strength = 31 (new BCryptPasswordEncoder(31)).
When I run my webapp and try to do a login with a user, I get the error Bad number of rounds.

Analysis:
As far as I have seen this is because within org.springframework.security.crypto.bcrypt.BCrypt, method crypt_raw(...) roundsForLogRounds method is called with log_rounds = 31 and returns the value 2147483648, but this calculated value is greater than Integer.MAX_VALUE (=2147483647) and thus results in the mentioned error.
See the following code in crypt_raw():

rounds = roundsForLogRounds(log_rounds);
if (rounds < 16 || rounds > Integer.MAX_VALUE) {
    throw new IllegalArgumentException("Bad number of rounds");
}

Expected behaviour:
As far as I have seen in the JavaDoc and in the source of Spring Security, BCryptPasswordEncoder accepts a strength (= log rounds) between 4 (inclusive) and 31 (inclusive). So 31 should be ok and the resulting Bad number of rounds error is probably a bug.

Version
Spring Boot v2.7.1
Spring v5.3.21
Spring Security v5.7.2

With Spring Boot v2.6.6 and Spring Security v5.6.2 strength = 31 worked as expected. Maybe the behaviour changed in commit e6297d3 ?

Metadata

Metadata

Assignees

Labels

in: cryptoAn issue in spring-security-cryptostatus: backportedAn issue that has been backported to maintenance branchestype: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions