密码加盐(盐值salt)

在讲述密码加盐之前,我们先梳理一下,我们常见的密码及加密方式
明文密码
   所谓明文密码就是没有对密码做任何加密措施,前台传到后台的是 "123456",后台数据库中保存的就是"123456",这种密码没有什么安全可言,数据库被拷走,那么用户的信息就被连锅端了。

简易密码加密
   所谓简易密码加密,就是后台服务自己定义一些简单的加密方式,如:密码反着存、密码加前后缀、密码字符串中指定字符被替换等等。这种密码乍看有点加密的意思,但是你都被黑客大哥给攻破了,你的数据库,后台加密程序都被人家拿走了,那不还是相当给人家的明文嘛。所以也很不安全。

 MD5 加密
   我知道的第一个正经的加密方式就是MD5, 因为MD5加密是非对称加密,是不可逆的。就是给你用MD5算法加密后的字符串,你是没有任何算法可以反向推算出原始密码的。既然反向推算不出来,那就很安全了吧。也不尽然。因为同一个文本通过MD5加密后,生成的密文是固定不变的,所以通过彩虹表进行撞库,还是能简简单单的破译你的密码。

 密码加盐
   MD5算法的加密方式,其实挺好的,但是固定长度的纯文本加密容易被撞库,既然如此,那么我们就在保存到数据库之前,在把被MD5加密过后的字符串添加点东西,主要身份就是“搅屎棍”,也被称之为加盐。原来是这样的MD5(password), 现在是这样的MD5(MD5(password) + salt),或者是其他算法,这里的salt就是“盐”,是后台服务器在保存密码时,生成的一段随机数串,这样生成最终加盐后的字符串就很安全了。

对称加密与非对称加密
  对称加密
   对称加密中,加密和解密使用同一把钥匙,数据发送方与接收方在数据传输前商定出一把共用的密钥,发送方数据传输前使用密钥进行加密,密文传输给接收方,接收方使用密钥进行解密,获得原始数据。

  非对称加密
   非对称加密,就是一共有两把钥匙,公共密钥与私有密钥。二者是成对存在的,使用公钥加密后,必须使用私钥才能解密出原始数据。数据发送方使用公钥对数据进行加密,数据发送到数据接收方,数据接收方使用私钥对密文进行解密,获得原始数据。

比较
对称加密
优点:算法简单,效率高,速度快。
缺点:不安全,密文与密钥泄露,数据也就泄露了。

非对称加密
优点:安全,即使公钥泄露,如果不同时获取到私钥,也无法解析出密文。所以数据接收方要保护好私钥。
缺点:算法相对复杂,加密与解密过程效率相对很低。

密码加盐
      密码加盐主要是针对用户的登录密码而言的,原始密码经过MD5(一种Hash算法)加密后,一些固定长度的简单纯文本密码的密文也会被破解出来。因为同一串字符的Hash加密后的密文是固定不变的。所以还是会被破解。


       破解的常用方法有暴力破解和字典破解,也是最笨拙的方法,就是一个一个试。所以二者的破解方法在时间(速度)和空间(存储)上都需要很大的资源,这样破解密码的效率极低。


       此路不通就另择他法,比如,使用彩虹表进行反向推出你的密码,彩虹表中是一些常用的固定长度的纯文本的哈希值,当这张表越大,破解密码的机率就越大。所以对于使用哈希算法加密的方式也就不那么安全了。如果被加密的原文不是固定的,那样彩虹表就很难进行哈希码对照了。也就更安全了。


      这种方法就是常说的“加盐”。盐(Salt)就是一个随机生成的字符串,每次修改密码或者操作,都会生成新的随机字符串,将原始密码进行哈希算法之后,进行加盐,就是把随机字符串混入到密码哈希值中,再将这个值再次进行哈希算法计算,这样生成的密文就更安全了。


     MD5(MD5(password) + salt)        加盐算法

       这样密码就很安全了。我们需要把盐保存起来,一般建议盐的保存位置与密文在不同的库中。因为用户登陆时我们需要使用用户输入的密码明文与盐进行上面的双重哈希算法计算出密文与数据库中的密文进行对比是否相同。如果盐被整丢了,那就完犊子了,因为上面的MD5算法需要两个参数(密码原文与盐),缺一不可。没有盐,就无法计算出密文进行对比。
 

### Spring Security 用户密码加盐实现方法 在实际项目中,为了增强密码的安全性,通常会使用加盐的方式对用户密码进行加密。Spring Security 提供了多种方式来实现密码加盐的功能,以下将详细介绍几种常见的实现方法。 #### 1. 使用 BCryptPasswordEncoder 自动加盐 Spring Security 内置的 `BCryptPasswordEncoder` 是一种强大的密码加密工具,它在加密时会自动添加随机[^3]。这意味着每次加密同一密码时都会生成不同的结果,从而避免了彩虹表攻击的风险。 ```java // 示例代码:使用 BCryptPasswordEncoder 进行密码加密 @Test public void testBcryptPasswordEncoder() { BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); String rawPassword = "123456"; String encodedPassword = passwordEncoder.encode(rawPassword); System.out.println("加密后的密码: " + encodedPassword); } ``` 通过上述代码可以看出,即使多次加密相同的原始密码,每次生成的加密结果也不同,这是因为 `BCryptPasswordEncoder` 在内部实现了自动加盐机制。 #### 2. 手动实现动态加盐 如果需要更灵活地控制,可以手动实现动态加盐逻辑。例如,在用户注册时生成一个唯一的,并将其与用户信息一起存储到数据库中。在验证密码时,结合重新计算哈希并与存储的密码进行比对。 ```java // 示例代码:手动实现动态加盐 private Function<String, String> passwordEncoder(String salt) { return rawPassword -> SecureUtil.md5(rawPassword + salt); // 使用 MD5 加密算法 } @Test public void testDynamicSalt() { String rawPassword = "123456"; String salt = UUID.randomUUID().toString(); // 生成唯一 String encodedPassword = passwordEncoder(salt).apply(rawPassword); System.out.println("加密后的密码: " + encodedPassword); System.out.println("使用的: " + salt); } ``` 在此示例中,`salt` 被用作动态,确保每次加密的结果都具有唯一性[^2]。 #### 3. 结合数据库存储 在企业级应用中,通常会将与用户信息一同存储到数据库中。这样可以在验证密码时提取对应的,完成密码的重新加密和比对。 ```sql -- 数据库表设计示例 CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password_hash VARCHAR(255) NOT NULL, salt VARCHAR(255) NOT NULL ); ``` 在用户登录时,从数据库中读取用户的,并使用该重新计算密码哈希: ```java // 示例代码:结合数据库存储 public boolean verifyPassword(String username, String inputPassword) { // 假设从数据库中查询到的用户信息 String storedPasswordHash = "hashed_password_from_db"; String salt = "salt_value_from_db"; String encodedInputPassword = passwordEncoder(salt).apply(inputPassword); return encodedInputPassword.equals(storedPasswordHash); } ``` 此方法确保了每个用户的密码都有独立的,进一步提升了系统的安全性[^4]。 #### 4. 配置 Spring Security 使用自定义密码编码器 如果需要在 Spring Security 中使用自定义的加盐逻辑,可以通过配置 `AuthenticationManagerBuilder` 来指定密码编码器。 ```java // 示例代码:配置 Spring Security 使用自定义密码编码器 @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user") .password(passwordEncoder().encode("123456")) .roles("USER"); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ``` 通过上述配置,Spring Security 将使用 `BCryptPasswordEncoder` 对用户密码进行加密和验证。 --- ### 总结 Spring Security 提供了多种方式来实现用户密码加盐的功能,包括内置的自动加盐机制(如 `BCryptPasswordEncoder`)以及手动实现动态加盐逻辑。根据实际需求,可以选择适合的方案以提升系统的安全性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值