Spring Security> 5.0.0 удален Md5PasswordEncoder

У меня есть проект Spring, использующий безопасность Spring. Я использовал Spring Boot 1.5, а теперь перешел на Spring Boot 2.0.

Я заметил, что Md5PasswordEncoder был удален в последней версии Spring Security. Вместо этого Md4PasswordEncoder все еще присутствует, даже если устарел (https://docs.spring.io/spring-security/site/docs/5.0.3.RELEASE/api/).

Должен ли я использовать внешний кодировщик MD5 или класс перемещен в другое место?

Вам вообще не следует использовать MD5.

Kayaman 03.04.2018 17:25
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
11
1
14 627
5

Ответы 5

Вместо этого вы должны использовать org.springframework.security.crypto.password.PasswordEncoder. Здесь - хорошая статья о переходе на новый интерфейс.

Я нашел эту статью более интуитивной baeldung.com/spring-security-5-password-storage

Jonathas Pacífico 27.11.2018 20:01

Spring удалите MD5, потому что он уже недостаточно безопасен. Вам следует использовать Bcrypt.

Мне нужно использовать MD5, потому что платежный шлюз требует хеширования некоторой части запроса с помощью MD5. Это не мой выбор ;-) Я использую Bcrypt для всего остального.

drenda 03.04.2018 18:58

Тот факт, что Md5PasswordEncoder прекратил свое существование, не означает, что Spring Security 5 не может создавать хэши MD5. Для этого используется new MessageDigestPasswordEncoder("MD5").

Есть два варианта, оба работают с новым DelegatingPasswordEncoder, который ожидает, что префикс пароля определяет алгоритм хеширования, например {MD5}password_hash:

Либо устанавливает кодировщик пароля по умолчанию на MD5 (в верхнем регистре!), Поэтому, если пароли не имеют префикса, применяется кодировщик по умолчанию:

PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
passwordEncoder.setDefaultPasswordEncoderForMatches(new MessageDigestPasswordEncoder("MD5"));

Или же префикс существующих хэшей паролей в базе данных с {MD5}. Таким образом, DelegatingPasswordEncoder делегирует хешеру MD5. Что-то вроде:

update myusertable set pwd = '{MD5}' || pwd;

Можете ли вы указать, какой пакет включить для PasswordEncoderFactories?

slashdottir 03.03.2021 01:19

это должен быть org.springframework.security.crypto.factory.PasswordEncoderF‌​actories от spring-security-core

Markus Pscheidt 03.03.2021 07:48

Если вы хотите использовать MD5, вы можете настроить:

@Bean
public PasswordEncoder passwordEncoder() {
    return new PasswordEncoder() {
        @Override
        public String encode(CharSequence charSequence) {
            return getMd5(charSequence.toString());
        }

        @Override
        public boolean matches(CharSequence charSequence, String s) {
            return getMd5(charSequence.toString()).equals(s);
        }
    };
}

public static String getMd5(String input) {
    try {
        // Static getInstance method is called with hashing SHA
        MessageDigest md = MessageDigest.getInstance("MD5");

        // digest() method called
        // to calculate message digest of an input
        // and return array of byte
        byte[] messageDigest = md.digest(input.getBytes());

        // Convert byte array into signum representation
        BigInteger no = new BigInteger(1, messageDigest);

        // Convert message digest into hex value
        String hashtext = no.toString(16);

        while (hashtext.length() < 32) {
            hashtext = "0" + hashtext;
        }

        return hashtext;
    }

    // For specifying wrong message digest algorithms
    catch (NoSuchAlgorithmException e) {
        System.out.println("Exception thrown"
                + " for incorrect algorithm: " + e);
        return null;
    }
}

Мое решение, как показано ниже:

protected static String mergePasswordAndSalt(String password, Object salt, boolean strict) {
        if (password == null) {
            password = "";
        }

        if ((strict) && (salt != null) && ((salt.toString().lastIndexOf("{") != -1) || (salt.toString().lastIndexOf("}") != -1))) {
            throw new IllegalArgumentException("Cannot use { or } in salt.toString()");
        }

        if ((salt == null) || ("".equals(salt))) {
            return password;
        }
        return password + "{" + salt.toString() + "}";
    }

    public static String EncodingPassword(String password, String salt) {
        String merge = mergePasswordAndSalt(password,salt,false);
        return DigestUtils.md5Hex(merge);
    }

используйте указанную выше функцию, чтобы заменить приведенный ниже код:

new  Md5PasswordEncoder().encodePassword(String rawPass, Object salt);

Из исходного кода Md5PasswordEncoder в spring-security-core-3.1.4.RELEASE.jar мы можем узнать, как он обрабатывает пароль и соль:

  //org.springframework.security.authentication.encoding.BasePasswordEncoder.class

  protected String mergePasswordAndSalt(String password, Object salt, boolean strict)
  {
    if (password == null) {
      password = "";
    }

    if ((strict) && (salt != null) && (
      (salt.toString().lastIndexOf("{") != -1) || (salt.toString().lastIndexOf("}") != -1))) {
      throw new IllegalArgumentException("Cannot use { or } in salt.toString()");
    }

    if ((salt == null) || ("".equals(salt))) {
      return password;
    }
    return password + "{" + salt.toString() + "}";
  }

Другие вопросы по теме