我的 Spring 安全项目中的 BCrypt(Spring 安全)
BCrypt in my Spring Security project (Spring security)
如何进行加密。这样在数据库中它就不会显示用户密码。我现在保存在数据库中 - 登录名和密码,用户角色。我需要密码必须加密(BCrypt)
在数据库中
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasRole("USER")
.antMatchers("/**").permitAll()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/allStudents")
.and()
.logout()
.and()
.csrf().disable();
}
@Bean
public PasswordEncoder weDoNotWantEncryption() {
return new PasswordEncoder() {
@Override
public String encode(CharSequence rawPassword) {
return rawPassword.toString();
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return rawPassword.toString().equals(encodedPassword);
}
};
}
}
非常简单 - 只需将您的 weDoNotWantEncryption()
函数替换为 returns 一个 BCrypt 实例:
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
BCryptPasswordEncoder
实现了 PasswordEncoder
(顾名思义),因此已经为 encode()
和 matches()
.
定义了好的方法
请注意,这将(当然)使您数据库中当前的所有密码无法使用,尽管鉴于这些密码以明文形式存储,我假设(并且 hope/pray)这是在测试环境中,而不是生产。
当我们加密存储密码时,我们通常对它们进行哈希处理,这样它是一种单向加密,即即使我们知道哈希算法,我们也无法从加密的密码中检索到原始密码。
我们执行此操作的主要过程如下。
- 取字符串"password"
- 向密码添加盐(一个随机字符串,以确保具有相同密码的多个用户没有相同的散列密码):随机盐:"A3fcherf42",生成的字符串:"A3fcherf42password"
- 使用加密算法散列该字符串,您可能会得到:"d143d1w132dd23dsgrg5"
- 将盐附加到加密密码以供将来验证用户登录时使用:"A3fcherf42d143d1w132dd23dsgrg5"
- 用用户id
保存在数据库中
现在验证用户登录:
- 从登录表单获取密码即"password"
- 读取存储在数据库中的哈希:"A3fcherf42d143d1w132dd23dsgrg5"
- 从存储的散列密码中提取盐:"A3fcherf42"
- 将盐附加到用户输入的密码:"A3fcherf42password"
- 对密码进行哈希处理,现在生成的哈希值应该与存储在数据库中的哈希值匹配。
使用 Bcrypt 执行此操作是一个简单的过程,因为大部分工作都由库处理。我解释了上面的场景,以便您对幕后发生的事情有一个很好的理解。您执行以下操作以生成并保存散列密码。
String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt());
现在您有了散列字符串,将其存储到数据库中。
当用户登录时,你获取他输入的密码,数据库存储的哈希字符串,并验证它。
if (BCrypt.checkpw(entered_pw, stored_hash))
return True;
请参阅此处关于 BCrypt 散列的 spring 安全文档:
如何进行加密。这样在数据库中它就不会显示用户密码。我现在保存在数据库中 - 登录名和密码,用户角色。我需要密码必须加密(BCrypt) 在数据库中
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasRole("USER")
.antMatchers("/**").permitAll()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/allStudents")
.and()
.logout()
.and()
.csrf().disable();
}
@Bean
public PasswordEncoder weDoNotWantEncryption() {
return new PasswordEncoder() {
@Override
public String encode(CharSequence rawPassword) {
return rawPassword.toString();
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return rawPassword.toString().equals(encodedPassword);
}
};
}
}
非常简单 - 只需将您的 weDoNotWantEncryption()
函数替换为 returns 一个 BCrypt 实例:
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
BCryptPasswordEncoder
实现了 PasswordEncoder
(顾名思义),因此已经为 encode()
和 matches()
.
请注意,这将(当然)使您数据库中当前的所有密码无法使用,尽管鉴于这些密码以明文形式存储,我假设(并且 hope/pray)这是在测试环境中,而不是生产。
当我们加密存储密码时,我们通常对它们进行哈希处理,这样它是一种单向加密,即即使我们知道哈希算法,我们也无法从加密的密码中检索到原始密码。
我们执行此操作的主要过程如下。
- 取字符串"password"
- 向密码添加盐(一个随机字符串,以确保具有相同密码的多个用户没有相同的散列密码):随机盐:"A3fcherf42",生成的字符串:"A3fcherf42password"
- 使用加密算法散列该字符串,您可能会得到:"d143d1w132dd23dsgrg5"
- 将盐附加到加密密码以供将来验证用户登录时使用:"A3fcherf42d143d1w132dd23dsgrg5"
- 用用户id 保存在数据库中
现在验证用户登录:
- 从登录表单获取密码即"password"
- 读取存储在数据库中的哈希:"A3fcherf42d143d1w132dd23dsgrg5"
- 从存储的散列密码中提取盐:"A3fcherf42"
- 将盐附加到用户输入的密码:"A3fcherf42password"
- 对密码进行哈希处理,现在生成的哈希值应该与存储在数据库中的哈希值匹配。
使用 Bcrypt 执行此操作是一个简单的过程,因为大部分工作都由库处理。我解释了上面的场景,以便您对幕后发生的事情有一个很好的理解。您执行以下操作以生成并保存散列密码。
String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt());
现在您有了散列字符串,将其存储到数据库中。
当用户登录时,你获取他输入的密码,数据库存储的哈希字符串,并验证它。
if (BCrypt.checkpw(entered_pw, stored_hash))
return True;
请参阅此处关于 BCrypt 散列的 spring 安全文档: