java Spring Security >5.0.0 删除了 Md5PasswordEncoder

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49633672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 10:24:58  来源:igfitidea点击:

Spring Security >5.0.0 removed Md5PasswordEncoder

javaspringspring-bootspring-security

提问by drenda

I have a Spring project using Spring security. I was using Spring Boot 1.5 and now I migrated to Spring Boot 2.0.

我有一个使用 Spring 安全性的 Spring 项目。我使用的是 Spring Boot 1.5,现在我迁移到 Spring Boot 2.0。

I noticed that Md5PasswordEncoderhas been removed in the final release of Spring Security. Instead Md4PasswordEncoderis still present even if deprecated (https://docs.spring.io/spring-security/site/docs/5.0.3.RELEASE/api/).

我注意到Md5PasswordEncoder已在 Spring Security 的最终版本中删除。相反,Md4PasswordEncoder即使弃用仍然存在(https://docs.spring.io/spring-security/site/docs/5.0.3.RELEASE/api/)。

Should I use extenal MD5 encoder or is the classed moved somewhere else?

我应该使用外部 MD5 编码器还是将分类移动到其他地方?

回答by Markus Pscheidt

The fact that Md5PasswordEncoderceased to exist doesn't mean that Spring Security 5 isn't able to create MD5hashes. It uses new MessageDigestPasswordEncoder("MD5")for that.

Md5PasswordEncoder不复存在的事实并不意味着 Spring Security 5 无法创建MD5哈希。它new MessageDigestPasswordEncoder("MD5")用于那个。

There are two options, both work with the new DelegatingPasswordEncoder, which expects a password prefix to determine the hashing algorithm, for example {MD5}password_hash:

有两个选项,都与 new 一起使用DelegatingPasswordEncoder,它需要一个密码前缀来确定散列算法,例如{MD5}password_hash

Eitherset the default password encoder to MD5(in uppercase!), so if passwords aren't prefixed, then the default encoder is applied:

要么将默认密码编码器设置为MD5(大写!),因此如果密码没有前缀,则应用默认编码器:

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

Orprefix the existing password hashes in the database with {MD5}. This way the DelegatingPasswordEncoderdelegates to the `MD5' hasher. Something like:

或者在数据库中的现有密码哈希前加上{MD5}. 这样就DelegatingPasswordEncoder代表了'MD5'散列器。就像是:

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

回答by TungHarry

If you want to use MD5 you can customize :

如果你想使用 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;
    }
}

回答by Matteo Baldi

You should use org.springframework.security.crypto.password.PasswordEncoderinstead. Hereis a good article about switching to the new interface.

你应该org.springframework.security.crypto.password.PasswordEncoder改用。是一篇关于切换到新界面的好文章。

回答by idan

Spring remove MD5 because it is not secure enough anymore. You should use Bcrypt.

Spring 删除 MD5,因为它不再足够安全。你应该使用 Bcrypt。

回答by u4915448

My solution as below:

我的解决方案如下:

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);
    }

use the function above to replace the code below:

使用上面的函数替换下面的代码:

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

From the source code of Md5PasswordEncoder in spring-security-core-3.1.4.RELEASE.jar, we can find out how it handle the password and salt:

从 spring-security-core-3.1.4.RELEASE.jar 中 Md5PasswordEncoder 的源码可以看出它是如何处理密码和盐的:

  //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() + "}";
  }