springsecurity 中的 BCrypt 加密算法

一、简介

1️⃣BCrypt 加密:一种加盐的单向 Hash,不可逆的加密算法,同一种明文,每次加密后的密文都不一样,而且不可反向破解生成明文,破解难度很大。每次加密的时候首先会生成一个随机数就是盐,之后将这个盐值与明文密码进行 hash,得到 一个hash值存到数据库中。其中生成的 hash 值中包含了之前生成的盐值(22个字符),用于后续 hash 值验证。

2️⃣MD5 加密:是不加盐的单向 Hash,不可逆的加密算法,同一个密码经过 hash 的时候生成的是同一个 hash 值,在大多数的情况下,有些经过 md5 加密的方法将会被破解。

二、过程

1️⃣生成盐值 salt。调用 BCrypt 类的构造函数,具体如下:

BCrypt.gensalt();
BCrypt.gensalt(String strength);
BCrypt.gensalt(String strength, SecureRandom secureRandom );

其中 strength 是散列数因子,范围是 4 到 31,默认是 10。random 是随机数产生器,也就是 new SecureRandom() 这个。

2️⃣生成加密字符串 hashed。调用 BCrypt 类的 hashpw(String password, String salt)。其中 password 是明文密码,salt 是第一步生成的盐值。

BCrypt.hashpw(rawPassword.toString(), salt)

3️⃣验证密文是否正确。调用 BCrypt 类的checkpw(String plaintext, String hashed)。其中 plaintext 是需要传入的明文,hashed 是第二步生成的密文。

BCrypt.checkpw(rawPassword.toString(), encodedPassword)

该方法返回布尔类型,true 表示验证通过,false 表示不通过。

进一步解析checkpw(String plaintext, String hashed)函数:

public static boolean checkpw(String plaintext, String hashed) {
    return equalsNoEarlyReturn(hashed, hashpw(plaintext, hashed));
}
static boolean equalsNoEarlyReturn(String a, String b) {
    char[] caa = a.toCharArray();
    char[] cab = b.toCharArray();
    if (caa.length != cab.length) {
        return false;
    }
    byte ret = 0;
    for (int i = 0; i < caa.length; i++) {
        ret |= caa[i] ^ cab[i];
    }
    return ret == 0;
}

源码中可以看出,先是把密文 hashed 当作盐值,和明文 plaintext 做加密算法,算法函数是hashpw(plaintext, hashed);。返回的加密结果跟之前计算的加密结果做对比,对比函数是equalsNoEarlyReturn(String a, String b);。一样则 true 表示验证通过,否则验证不通过。

三、BCryptPasswordEncoder

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class Test {
    public static void main(String[] args) {

        String password = "123456";
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(6);
        String hashedPassword1 = passwordEncoder.encode(password);
        String hashedPassword2 = passwordEncoder.encode(password);
        String hashedPassword3 = passwordEncoder.encode(password);
        String hashedPassword4 = passwordEncoder.encode(password);
        System.out.println(hashedPassword1);
        System.out.println(hashedPassword2);
        System.out.println(hashedPassword3);
        System.out.println(hashedPassword4);

        boolean match1 = passwordEncoder.matches(password, hashedPassword1);
        System.out.println(match1);
        boolean match2 = passwordEncoder.matches(password, hashedPassword2);
        System.out.println(match2);
        boolean match3 = passwordEncoder.matches(password, hashedPassword3);
        System.out.println(match3);
        boolean match4 = passwordEncoder.matches(password, hashedPassword4);
        System.out.println(match4);
    }
}

结果如下:

$2a$06$.PnAp0jsfeTND2yBjdfFcuV0VoNQ6.E5hHDxWRrmGDuGxV3bj/zUS
$2a$06$Juq9dexQqveFiJhcPqZ/SeuEGB8/BtLMyCpYBNEfnm4F2HG/FFK9y
$2a$06$yCT1TPwWOpWr5.OrAdis5OOvbCOSmBuadibbxO7zajSChsAwFC8R6
$2a$06$cCMPkgZc7s2lB06fWG6SnO8nsZvBwXr0eZZFkLo16pLjk8A/XN196
true
true
true
true

登录注册还是用https安全。在客户端 base64 或者 md5 什么的真心没用,直接监听到所谓的密文,然后用脚本发起一个 http 请求就可以登录上去了。http 在网络上是明文传输的,代理和网关都能看到所有的数据,在同一局域网内也可以被嗅探到,可以开个 wireshark 抓下局域网的包试试看。我认为加密也没有提高什么攻击难度,因为攻击者就没必要去解密原始密码,能登录上去就表示目标已经实现了,所以难度没有提高。另外,在客户端md5后,服务端怎么把原始密码还原出来,不能数据库直接存 md5 吧?所以要选择加密算法的话,还要让服务端能还原出来原始密码。然后,如果是简单的 base64 下,这种算法对安全性没什么提高,base64 又不是加密算法,它的作用就是编码而已。其他的诸如非对称加密之类的算法当然可以,但是这不是https提供的功能么?而且 https 提供的安全保障还可以应对其他的攻击。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Spring Security 是一个常用的安全框架,它提供了许多安全功能,例如身份验证、授权等。BCrypt 是一个常用的密码加密算法,它可以安全地存储用户密码。 Spring Security 支持使用 BCrypt 加密算法来加密用户密码。使用 BCrypt 加密算法可以确保用户密码的安全性,因为 BCrypt 算法使用 salt(盐)和随机的哈希函数来防止彩虹表攻击。以下是 Spring Security 集成 BCrypt 的步骤: 1. 添加 BCrypt 依赖 首先,需要在项目添加 BCrypt 的依赖。如果使用 Maven,可以在 pom.xml 文件添加以下依赖: ``` <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-crypto</artifactId> <version>5.5.1</version> </dependency> ``` 2. 配置 BCryptPasswordEncoder BCryptPasswordEncoder 是 Spring Security 提供的一个实现了 BCrypt 加密算法的密码编码器。需要在 Spring Security 的配置类配置 BCryptPasswordEncoder。例如: ``` @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Bean public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); } // Other configuration } ``` 在上面的配置,首先注入了一个 UserDetailsService,然后定义了一个 bCryptPasswordEncoder 方法,返回一个 BCryptPasswordEncoder 对象,该对象将用于加密密码。最后在 configure 方法配置 AuthenticationManagerBuilder,将 userDetailsService 和 bCryptPasswordEncoder 一起使用。 3. 使用 BCryptPasswordEncoder 加密密码 当需要创建用户或更改用户密码时,可以使用 BCryptPasswordEncoder 对密码进行加密。例如: ``` @Autowired private BCryptPasswordEncoder bCryptPasswordEncoder; // ... User user = new User(); user.setUsername("john.doe"); user.setPassword(bCryptPasswordEncoder.encode("password")); ``` 在上面的代码,首先注入了一个 BCryptPasswordEncoder,然后创建了一个新的用户对象,使用 bCryptPasswordEncoder.encode 方法将密码加密后设置到用户对象。 使用 BCryptPasswordEncoder 加密用户密码可以有效地保护用户密码的安全性。 ### 回答2: Spring Security是一个用于在Java应用提供身份认证、授权和安全保护的框架。BCrypt是一种密码哈希函数,用于在存储密码时进行加密和验证。 Spring Security提供了与BCrypt的集成支持,在使用BCrypt进行密码加密和验证时可以方便地与Spring Security进行整合。 在集成BCrypt之前,我们需要将BCrypt作为一个依赖项添加到我们的项目。可以通过Maven或Gradle来配置依赖。 添加了BCrypt依赖项后,我们可以使用Spring Security提供的PasswordEncoder接口的实现类BCryptPasswordEncoder来进行密码加密和验证。 在注册或更新用户密码时,我们可以使用BCryptPasswordEncoder对密码进行加密,然后将加密后的密码保存到数据库。示例代码如下: ``` BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); String rawPassword = "123456"; String encodedPassword = encoder.encode(rawPassword); // 将encodedPassword保存到数据库 ``` 在用户登录时,我们可以使用BCryptPasswordEncoder对用户输入的密码进行验证,示例代码如下: ``` BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); String rawPassword = "123456"; String encodedPassword = "从数据库获取的加密密码"; boolean isPasswordMatch = encoder.matches(rawPassword, encodedPassword); // 如果isPasswordMatch为true,表示密码匹配成功 ``` 通过以上代码,我们可以实现在Spring Security使用BCrypt进行密码加密和验证的集成。 BCrypt提供了一种强大的密码保护机制,通过与Spring Security的集成可以更方便地在我们的应用提供安全的用户认证和授权。 ### 回答3: Spring Security 是一个用于身份验证和授权的开源框架,而 BCrypt 则是一种密码加密算法。 在 Spring Security 集成 BCrypt 可以提供更高级别的密码安全性。BCrypt 是一种单向哈希函数,它将密码转换为一个不可逆的哈希值,从而保护用户密码的安全性。BCrypt 不仅可以对用户的密码进行哈希和验证,还可以自动处理密码的盐和计算哈希的循环次数。 Spring Security 集成 BCrypt 的步骤如下: 第一步,需要在项目的构建文件添加 BCrypt 的依赖,例如 Maven: ```xml <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-crypto</artifactId> <version>5.6.1</version> </dependency> ``` 第二步,需要在 Spring Security 的配置文件配置密码编码器。可以通过使用 `BCryptPasswordEncoder` 类来创建一个密码编码器Bean: ```java @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } ``` 第三步,使用密码编码器对用户的密码进行编码和验证。在注册用户时,需要通过密码编码器将明文密码转换为 BCrypt 哈希值: ```java String hashedPassword = passwordEncoder.encode(password); ``` 在验证该用户登录时,需要使用密码编码器验证用户输入的密码和数据库存储的哈希值是否匹配: ```java if(passwordEncoder.matches(inputPassword, hashedPassword)) { //密码匹配,登录成功 } else { //密码不匹配,登录失败 } ``` 通过以上步骤,我们成功集成了 BCrypt 算法,保障了密码的安全性。尽管这个过程可能略微复杂,但是通过 Spring Security 的支持,我们可以轻松地实现密码加密和验证的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

JFS_Study

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

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

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

打赏作者

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

抵扣说明:

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

余额充值