背景
在授权的管理方面,Spring security 不愧是一个成熟的框架,本身有spring这个大的生态支持,再加上近几年Spring Boot的大力支持,现在Spring security在授权方面的入门门槛高的问题,也被解决了。这些问题被解决了,那么咱们是不是可以深入的了解一下spring security的一些设计。下面从spring security推荐的一个密码加密工具类来作为一个引导,会在将来一步一步的深入。
接口PasswordEncoder
接口设计的简单明了,一个用来加密密码,另一个用来匹配是否与原密码相等,接口本身在org.springframework.security.crypto.password
包下,crypto是为了提供通用的加密和哈希算法的,
Bcrypt
bcrypt是一个由Niels Provos以及David Mazières根据Blowfish加密算法所设计的密码散列函数,于1999年在USENIX中展示。实现中bcrypt会使用一个加盐的流程以防御彩虹表攻击,同时bcrypt还是适应性函数,它可以借由增加迭代之次数来抵御日益增进的计算机运算能力透过暴力法破解。
在Bcrypt之前大部分的加密密码的操作有Md4,Md5等等的hash摘要算法,来处理密码的单向加密,但是随着彩虹表之类的工具库存在和hash碰撞的,用md5之类的处理密码的加密并不是一个非常安全的操作,Bcrypt是一个更好的加密算法,它加密的时候,同一个密码加密后的值不同,大概原理是,在hash时加入salt值来处理,让hash后的结果都不同,还有为了方便数据库不更改,这个算法可以保证同一个不需要再单独保存salt值,因为他在加密后会把salt值和hash之后的值都存在加密后的字符串中。那么接下来我们开始介绍java中的实现
BCryptPasswordEncoder
spring securit中已經提供了默认的一个bcrypt的密码加密工具类,本身该类提供了三个构造方法,无参数的,有一个参数的(参数为密码强度),有两个参数的(密码强度,随机因子)。
无参构造方法,如下
无参构造方法会传一个-1
到一个有参数的
public BCryptPasswordEncoder() {
this(-1);
}
一个参数的,可以设置密码强度
/**
* @param strength the log rounds to use, between 4 and 31
*/
public BCryptPasswordEncoder(int strength) {
this(strength, null);
}
可以设置密码强度和安全随机因子。并且密码强度本身是有最大值和最小值的限制的。分别是4到31
/**
* @param strength the log rounds to use, between 4 and 31
* @param random the secure random instance to use
*
*/
public BCryptPasswordEncoder(int strength, SecureRandom random) {
//BCrypt.MIN_LOG_ROUNDS = 4 and BCrypt.MAX_LOG_ROUNDS = 31
if (strength != -1 && (strength < BCrypt.MIN_LOG_ROUNDS || strength > BCrypt.MAX_LOG_ROUNDS)) {
throw new IllegalArgumentException("Bad strength");
}
this.strength = strength;
this.random = random;
}
这里抛出一个问题?为什么密码的最大强度和最小强度要大于等于4或者小于等于31
介绍为构造方法后,我们说一下,一般情况下我们使用默认的无参构造方法就可以,简单操作方便
加密方法本身只需要传入原始密码即可,传入后,原始密码根据,如果强度小于0时,salt的值为默认生成,这个遂成随机盐的方法咱们在下一步仔细看,这个方法中并没有太多的具体操作,具体实现都在BCrypt类中。
public String encode(CharSequence rawPassword) {
String salt;
if