Spring Security 使用 PBKDF2
PBKDF2加密原理
原理可以看下这篇文章 https://blog.csdn.net/horheart/article/details/119968850
Pbkdf2PasswordEncoder构造函数
public Pbkdf2PasswordEncoder(CharSequence secret, int saltLength, int iterations, SecretKeyFactoryAlgorithm secretKeyFactoryAlgorithm) {
this.algorithm = DEFAULT_ALGORITHM.name();
this.hashWidth = 256;
this.overrideHashWidth = true;
this.secret = Utf8.encode(secret);
this.saltGenerator = KeyGenerators.secureRandom(saltLength);
this.iterations = iterations;
this.setAlgorithm(secretKeyFactoryAlgorithm);
}
CharSequence secret : 我们的自己私钥 (额外的盐值) 最小为128位
Int saltLength : 随机盐值长度 一般在8-16字节
int iterations : 迭代次数 迭代次数越多安全性越高 但是所耗时越长
SecetKeyFactoryAlgorithm secretKeyFactoryAlgorithm : 算法 一般为SHA256 SHA512 SHA1
创建一个Pbkdf2PasswordEncoder 并注入我们的私钥
这里我们注入我们的128位私钥 secret
String sercet = "ah*(Y*dj1d262da)......";//此处为我们的128位私钥
Pbkdf2PasswordEncoder encoder = new Pbkdf2PasswordEncoder(secret,8,6,Pbkdf2PasswordEncoder.SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA256);//随机盐长度为8位,迭代次数为6次,这里我使用了SHA256算法
加密
String password = "Ab123456";//需要被加密的密码
String encoderPass = encoder.encode(password);//加密
检查原密码和加密后的是否匹配
String password = "Ab123456";//需要被加密的密码
String encoderPass = encoder.encode(password);//加密
boolean result = encode.matches(password,encoderPass);
案列
需要导入的包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
SecurityConfig
配置Pbkdf2PasswordEncoder
@Component
@RefreshScope
public class SecurityConfig {
/**
* 随机盐长度
*/
private static final int DEFAULT_SALT_LENGTH = 8;
/**
* 迭代次数
*/
private static final int DEFAULT_ITERATIONS = 6;
//@Value 从git仓库获取私钥
@Bean(name = "pbkdf2Encoder")
public Pbkdf2PasswordEncoder pbkdf2PasswordEncoder(@Value("${algorithm.pbkdf2.password.secret}")String secret){
return new Pbkdf2PasswordEncoder(secret,DEFAULT_SALT_LENGTH,DEFAULT_ITERATIONS,
Pbkdf2PasswordEncoder.SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA256);
}
}
EncryptionAlgorithm 接口
@Service
public interface EncryptionAlgorithm {
String encryption(String pass);
Boolean encodedEquals(String pass,String encodedPass);
}
PBKDF2Algorithm 实现类
@RefreshScope
@Service
@Slf4j
public class PBKDF2Algorithm implements EncryptionAlgorithm {
@Autowired
@Qualifier("pbkdf2Encoder")
Pbkdf2PasswordEncoder pbkdf2PasswordEncoder;
/**
* 加密
* @param pass password
* @return 加密后的128位密码
*/
@Override
public String encryption(String pass) {
return pbkdf2PasswordEncoder.encode(pass);
}
/**
* 匹配
* @param password 原密码
* @param encodedPassword 加密后的密码
* @return true 匹配 false 不匹配
*/
@Override
public Boolean encodedEquals(String password,String encodedPassword){
return pbkdf2PasswordEncoder.matches(password,encodedPassword);
}
}
EncryptionController
@RestController
@RequestMapping("/encryption")
public class EncryptionController {
@Autowired
EncryptionAlgorithm encryptionAlgorithm;
@GetMapping("/encode")
public String getEncodePassword(@RequestParam("password")String password){
return encryptionAlgorithm.encryption(password);
}
@GetMapping("/check/encoded")
public Boolean checkEncodePassword(@RequestParam("password")String password,
@RequestParam("encodedPassowrd")String encodedPassword){
return encryptionAlgorithm.encodedEquals(password,encodedPassword);
}
}
EncryptionTest 测试类
@RunWith(SpringRunner.class)
@SpringBootTest(classes = EncryptionApplication.class)
public class EncryptionTest {
@Autowired
EncryptionController controller;
@Test
public void testEncode(){
long time = System.currentTimeMillis();
String encodedPassword;
System.out.println(encodedPassword = controller.getEncodePassword("Ab123456"));
System.out.println(System.currentTimeMillis() - time + "ms");
System.out.println(controller.checkEncodePassword("Ab123456",encodedPassword));
System.out.println();
}
}
最后测试的结果