SpringSecurity(三)PasswordEncoder

  • 数据安全是很重要的事情,关键数据传输时,要加密;数据库里面的重要信息也要加密。

  • 在开始本章之前,我想先分享一个故事,上个星期我的一台服务器被勒索病毒攻击了,里面很多信息都没有了,数据库也没有了,只留下一个地址,让我给对方付0.03比特币(3000元左右),非常难受(上半年侥幸活下来了,下半年的事都有点难顶呀),平台说cpu没事,让我重装系统(甩锅,看来免费的东西都不怎么靠谱);平台给了我几条建议:

      1.禁用ROOT
      2.用户名和密码尽量复杂
      3.修改ssh的默认22端口
      4.安装DenyHosts防暴力破解软件
      5.禁用密码登录,使用RSA公钥登录
    
依赖

依赖注意事项:我们构建Web类型的安全项目时,spring-security-config、spring-security-core、spring-security-web三个依赖都是必须添加的。

PasswordEncoder

PasswordEncoder是Spring Security提供的密码加密方式的接口定义。

1)源码类如下所示:

package org.springframework.security.crypto.password;

public interface PasswordEncoder {
    //加密
    String encode(CharSequence var1);

    //匹配,第一个是客户端的明文密码,第二个是已经加密的密码
    boolean matches(CharSequence var1, String var2);

    //对于已经加密的密码再次加密
    default boolean upgradeEncoding(String encodedPassword) {
        return false;
    }
}
#encode

该方法提供了明文密码的加密处理,加密后密文的格式主要取决于PasswordEncoder接口实现类实例。

#matches

匹配存储的密码以及登录时传递的密码(登录密码是经过加密处理后的字符串)是否匹配,如果匹配该方法则会返回true.

2)它的一个主要默认实现类:BCryptPasswordEncoder

public class BCryptPasswordEncoder implements PasswordEncoder {
    private Pattern BCRYPT_PATTERN;
    private final Log logger;
    private final int strength;
    private final BCryptPasswordEncoder.BCryptVersion version;
    private final SecureRandom random;

    public String encode(CharSequence rawPassword) {
    if (rawPassword == null) {
        throw new IllegalArgumentException("rawPassword cannot be null");
    } else {
        String salt;
        if (this.random != null) {
            salt = BCrypt.gensalt(this.version.getVersion(), this.strength, this.random);
        } else {
            salt = BCrypt.gensalt(this.version.getVersion(), this.strength);
        }

        return BCrypt.hashpw(rawPassword.toString(), salt);
    }
}


    }

3)简单的一个demo

@SpringBootTest
class SpringSecuritySsoApplicationTests {

    @Test
    void contextLoads() {
        PasswordEncoder pw= new BCryptPasswordEncoder();
        //加密
        String encode=pw.encode("123");
        System.out.println(encode);
        //比较密码
        boolean matches=pw.matches("123",encode);
        System.out.println("==============================");
        System.out.println(matches);
    }

}

在这里插入图片描述

DelegatingPasswordEncoder

在之前版本集成Spring Security时,我们需要通过@Bean的方式去配置全局统一使用的密码加密方式(PasswordEncoder),这种方法现在用的也很多。

@Bean
public PasswordEncoder passwordEncoder() {
  return new BCryptPasswordEncoder();
}

但5.X版本开始为了支持多种加密方式,诞生了DelegatingPasswordEncoder委托加密方式类。

它内部其实是一个Map集合,根据传递的Key(Key为加密方式)获取Map集合的Value,而Value则是具体的PasswordEncoder实现类。

@Bean
PasswordEncoder passwordEncoder(){
    return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}

负责生产 DelegatingPasswordEncoder 的工厂方法:

public class PasswordEncoderFactories {

   public static PasswordEncoder createDelegatingPasswordEncoder() {
      String encodingId = "bcrypt";
      Map<String, PasswordEncoder> encoders = new HashMap<>();
      encoders.put(encodingId, new BCryptPasswordEncoder());
      encoders.put("ldap", new LdapShaPasswordEncoder());
      encoders.put("MD4", new Md4PasswordEncoder());
      encoders.put("MD5", new MessageDigestPasswordEncoder("MD5"));
      encoders.put("noop", NoOpPasswordEncoder.getInstance());
      encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
      encoders.put("scrypt", new SCryptPasswordEncoder());
      encoders.put("SHA-1", new MessageDigestPasswordEncoder("SHA-1"));
      encoders.put("SHA-256", new MessageDigestPasswordEncoder("SHA-256"));
      encoders.put("sha256", new StandardPasswordEncoder());

      return new DelegatingPasswordEncoder(encodingId, encoders);
   }

   private PasswordEncoderFactories(){}
}

如此注入 PasswordEncoder 之后,我们在数据库中需要这么存储数据:

{bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG 
{noop}password 
{pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc 
{scrypt}$e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==$OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc=  
{sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0

DelegatingPasswordEncoder默认使用的还是bcrypt加密方式

注意:

Spring Security 5中密码策略的变更:
(1)必须显式指定PasswordEncoder,
(2)存储的密码格式变为:{id}加密后的密文
(3)id是一个标识符,用于查找是哪个PasswordEncoder,也就是密码加密时使用的PasswordEncoder。密码必须以id开始,id前后必须加{}。如果id找不到,id则会为空。

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

希境

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值