Quellcode durchsuchen

Enforce BCrypt password length for new passwords only

Closes gh-16802
Joe Grandja vor 4 Monaten
Ursprung
Commit
c1aa99fdd2

+ 2 - 1
crypto/src/main/java/org/springframework/security/crypto/bcrypt/BCrypt.java

@@ -611,7 +611,8 @@ public class BCrypt {
 		int rounds, off;
 		StringBuilder rs = new StringBuilder();
 
-		if (passwordb.length > 72) {
+		// Enforce max length for new passwords only
+		if (!for_check && passwordb.length > 72) {
 			throw new IllegalArgumentException("password cannot be more than 72 bytes");
 		}
 		if (salt == null) {

+ 26 - 5
crypto/src/test/java/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoderTests.java

@@ -223,13 +223,34 @@ public class BCryptPasswordEncoderTests {
 	}
 
 	@Test
-	public void enforcePasswordLength() {
+	public void encodeWhenPasswordOverMaxLengthThenThrowIllegalArgumentException() {
 		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
+
 		String password72chars = "123456789012345678901234567890123456789012345678901234567890123456789012";
-		assertThat(encoder.matches(password72chars, encoder.encode(password72chars))).isTrue();
-		String password73chars = password72chars.concat("a");
-		assertThatIllegalArgumentException()
-			.isThrownBy(() -> encoder.matches(password73chars, encoder.encode(password73chars)));
+		encoder.encode(password72chars);
+
+		String password73chars = password72chars + "3";
+		assertThatIllegalArgumentException().isThrownBy(() -> encoder.encode(password73chars));
+	}
+
+	@Test
+	public void matchesWhenPasswordOverMaxLengthThenAllowToMatch() {
+		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
+
+		String password71chars = "12345678901234567890123456789012345678901234567890123456789012345678901";
+		String encodedPassword71chars = "$2a$10$jx3x2FaF.iX5QZ9i3O424Os2Ou5P5JrnedmWYHuDyX8JKA4Unp4xq";
+		assertThat(encoder.matches(password71chars, encodedPassword71chars)).isTrue();
+
+		String password72chars = password71chars + "2";
+		String encodedPassword72chars = "$2a$10$oXYO6/UvbsH5rQEraBkl6uheccBqdB3n.RaWbrimog9hS2GX4lo/O";
+		assertThat(encoder.matches(password72chars, encodedPassword72chars)).isTrue();
+
+		// Max length is 72 bytes, however, we need to ensure backwards compatibility
+		// for previously encoded passwords that are greater than 72 bytes and allow the
+		// match to be performed.
+		String password73chars = password72chars + "3";
+		String encodedPassword73chars = "$2a$10$1l9.kvQTsqNLiCYFqmKtQOHkp.BrgIrwsnTzWo9jdbQRbuBYQ/AVK";
+		assertThat(encoder.matches(password73chars, encodedPassword73chars)).isTrue();
 	}
 
 }