浏览代码

BCryptPasswordEncoder validates strength

Fixes gh-3862
Kim Saabye Pedersen 9 年之前
父节点
当前提交
9fcfeaf225

+ 5 - 3
crypto/src/main/java/org/springframework/security/crypto/bcrypt/BCrypt.java

@@ -257,6 +257,8 @@ public class BCrypt {
 			8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
 			-1, -1, -1, -1, -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
 			41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, -1, -1, -1, -1, -1 };
+	static final int MIN_LOG_ROUNDS = 4;
+	static final int MAX_LOG_ROUNDS = 31;
 	// Expanded Blowfish key
 	private int P[];
 	private int S[];
@@ -600,12 +602,12 @@ public class BCrypt {
 	/**
 	 * Generate a salt for use with the BCrypt.hashpw() method
 	 * @param log_rounds the log2 of the number of rounds of hashing to apply - the work
-	 * factor therefore increases as 2**log_rounds.
+	 * factor therefore increases as 2**log_rounds. Minimum 4, maximum 31.
 	 * @param random an instance of SecureRandom to use
 	 * @return an encoded salt value
 	 */
 	public static String gensalt(int log_rounds, SecureRandom random) {
-		if (log_rounds < 4 || log_rounds > 31) {
+		if (log_rounds < MIN_LOG_ROUNDS || log_rounds > MAX_LOG_ROUNDS) {
 			throw new IllegalArgumentException("Bad number of rounds");
 		}
 		StringBuilder rs = new StringBuilder();
@@ -626,7 +628,7 @@ public class BCrypt {
 	/**
 	 * Generate a salt for use with the BCrypt.hashpw() method
 	 * @param log_rounds the log2 of the number of rounds of hashing to apply - the work
-	 * factor therefore increases as 2**log_rounds.
+	 * factor therefore increases as 2**log_rounds. Minimum 4, maximum 31.
 	 * @return an encoded salt value
 	 */
 	public static String gensalt(int log_rounds) {

+ 8 - 5
crypto/src/main/java/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder.java

@@ -15,13 +15,13 @@
  */
 package org.springframework.security.crypto.bcrypt;
 
-import java.security.SecureRandom;
-import java.util.regex.Pattern;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-
 import org.springframework.security.crypto.password.PasswordEncoder;
 
+import java.security.SecureRandom;
+import java.util.regex.Pattern;
+
 /**
  * Implementation of PasswordEncoder that uses the BCrypt strong hashing function. Clients
  * can optionally supply a "strength" (a.k.a. log rounds in BCrypt) and a SecureRandom
@@ -45,18 +45,21 @@ public class BCryptPasswordEncoder implements PasswordEncoder {
 	}
 
 	/**
-	 * @param strength the log rounds to use
+	 * @param strength the log rounds to use, between 4 and 31
 	 */
 	public BCryptPasswordEncoder(int strength) {
 		this(strength, null);
 	}
 
 	/**
-	 * @param strength the log rounds to use
+	 * @param strength the log rounds to use, between 4 and 31
 	 * @param random the secure random instance to use
 	 *
 	 */
 	public BCryptPasswordEncoder(int strength, SecureRandom random) {
+		if (strength != -1 && (strength < BCrypt.MIN_LOG_ROUNDS || strength > BCrypt.MAX_LOG_ROUNDS)) {
+			throw new IllegalArgumentException("Bad strength");
+		}
 		this.strength = strength;
 		this.random = random;
 	}

+ 12 - 2
crypto/src/test/java/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoderTests.java

@@ -15,12 +15,12 @@
  */
 package org.springframework.security.crypto.bcrypt;
 
-import static org.assertj.core.api.Assertions.*;
-
 import org.junit.Test;
 
 import java.security.SecureRandom;
 
+import static org.assertj.core.api.Assertions.assertThat;
+
 /**
  * @author Dave Syer
  *
@@ -57,6 +57,16 @@ public class BCryptPasswordEncoderTests {
 		assertThat(encoder.matches("password", result)).isTrue();
 	}
 
+	@Test(expected = IllegalArgumentException.class)
+	public void badLowCustomStrength() {
+		new BCryptPasswordEncoder(3);
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void badHighCustomStrength() {
+		new BCryptPasswordEncoder(32);
+	}
+
 	@Test
 	public void customRandom() {
 		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(8, new SecureRandom());