SpringSecurity实战干货-如何更好的保护用户密码?

根据上篇文章中介绍的内容,我们对UserDetails有了进一步的了解,在示例中我们采用了明文的方式来传递了用户的密码,这样的做法是极度不安全的。那么这篇文章我们就来对用户密码加密来做一个深入的探讨了解。

不推荐MD5加密

想到加密,第一个想到的就是MD5。这里需要纠正的一个错误,其实严格来讲Md5应该不算是一个加密算法。因为它只是根据某种规则计算处理一个字符串的Hash表示方式。为什么这里可以称为加密的原因就是在于通过MD5的加密之后也可以达到一个密码保护的效果。但是这里我们不推荐MD5加密算法。因为我们知道有些密码的MD5值已经是被大多数人知道,根据MD5的值可以推测出密码是什么。所以不是太安全。

Spring Security 中推荐的算法

在上篇文章中,我们在分析UserDetailsServiceAutoConfiguration的源码的时候,提到了一个InMemoryUserDetailsManager管理器,并且在初始化Bean操作的时候调用了一个ObjectProvider passwordEncoder 进行了密码的加密。

会发现,在这个加密操作过程中,完成的操作就是密码的验证与密码的编码。分析源码可以知道,PasswordEncoder接口有一个子类DelegatingPasswordEncoder,从类名上可以看到DelegatingPasswordEncoder是一个代理类。

DelegatingPasswordEncoder

既然是个代理类,那么它代理的到底是谁呢?会看到,在这个代理中有如下的几个属性。

其编码规则如下

@Override
public String encode(CharSequence rawPassword) {
   return PREFIX + this.idForEncode + SUFFIX + this.passwordEncoderForEncode.encode(rawPassword);
}

从代码中可以看到通过DelegatingPasswordEncoder编码的规则。其密码匹配规则如下

@Override
public boolean matches(CharSequence rawPassword, String prefixEncodedPassword) {
   if (rawPassword == null && prefixEncodedPassword == null) {
      return true;
   }
   String id = extractId(prefixEncodedPassword);
   PasswordEncoder delegate = this.idToPasswordEncoder.get(id);
   if (delegate == null) {
      return this.defaultPasswordEncoderForMatches.matches(rawPassword, prefixEncodedPassword);
   }
   String encodedPassword = extractEncodedPassword(prefixEncodedPassword);
   return delegate.matches(rawPassword, encodedPassword);
}

密码的匹配是按照原始密码与计算之后的密码进行匹配,既然这样,那么这个DelegatingPasswordEncoder是在什么时候被初始化的呢?

PasswordEncoder的初始化

在DelegatingPasswordEncoder类代码中有一个描述是关于如何初始化的,使用了一个PasswordEncoderFactories工厂。

在这个工厂中有一个方法,如下图所示

从这个方法中可以看到,其实在Spring Security中提供了很多的加密方法。并且默认它使用的是bcrypt进行编码。

这个时候我们也理解了关于在上面提到的密码生成规则,以及密码匹配规则。

Spring Security如何加载PasswordEncoder规则

在Spring Security的配置中通过WebSecurityConfigurerAdapter进行配置,找到了PasswordEncoderFactories,并且加载了一个LazyPasswordEncoder类

从上面的方式来看,如果能从SpringIOC容器中获取到PasswordEncoder那么就使用PasswordEncoder作为编码器,如果没有就使用默认的DelegatingPasswordEncoder,默认的编码方式就是bcrypt。下面我们来看一下关于bcrypt算法。

bcrypt算法

bcrypt算法是Blowfish算法的改进算法,它是将salt随机混入后进行了加密,在验证的时候不需要再单独提供salt,可以避免对salt处理问题。

bcrypt算法最大的特点就是慢,但还这个时长对于开发人员来说是可以忍受的,在使用bcrypt编码的时候,密码的暗文是不一样的,所以如果两个网站都使用了bcrypt算法,也不会造成密码的泄漏。

所以bcrypt算法从特点上来看,安全性这些还是有保证的。

总结

上面,我们介绍了Spring Security中的密码编码的方式,并且了解了在默认情况下使用的bcrypt算法编码,并且了解了密码匹配规则。也介绍了关于自定义加密规则的实现原理。

展开阅读全文

页面更新:2024-04-14

标签:干货   初始化   算法   用户密码   实战   源码   加密算法   加载   规则   密码   操作   方式   方法

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top