/** * Verifies that a hash value is a valid BCrypt password hash. * <p> * The hash must be a version 2a hash and must not use more than the configured * maximum number of iterations as returned by {@link #getMaxBcryptIterations()}. * * @param pwdHash The hash to verify. * @throws IllegalStateException if the secret does not match the criteria. */ protected void verifyBcryptPasswordHash(final String pwdHash) { Objects.requireNonNull(pwdHash); if (BCryptHelper.getIterations(pwdHash) > getMaxBcryptIterations()) { throw new IllegalStateException("password hash uses too many iterations, max is " + getMaxBcryptIterations()); } } }
/** * Invoked as part of payload validation when adding or updating <em>hashed password</em> * credentials using the <em>bcrypt</em> hash algorithm. * <p> * Verifies that the hashed password matches the bcrypt hash pattern and doesn't use more * than the configured maximum number of iterations as returned by {@link #getMaxBcryptIterations()}. * * @param secret The secret to verify. * @throws IllegalArgumentException if the password hash is invalid. */ protected void verifyBcryptPasswordHash(final JsonObject secret) { final String pwdHash = ((JsonObject) secret).getString(CredentialsConstants.FIELD_SECRETS_PWD_HASH); final Matcher matcher = BCRYPT_PATTERN.matcher(pwdHash); if (matcher.matches()) { // check that hash doesn't use more iterations than configured maximum final int iterations = Integer.valueOf(matcher.group(1)); if (iterations > getMaxBcryptIterations()) { throw new IllegalArgumentException("max number of BCrypt iterations exceeded"); } } else { // not a valid bcrypt hash throw new IllegalArgumentException("not a BCrypt hash"); } }