目录
1 密码加密原则(续)
1.1 盐值的优化
1.2 Mybatis中的占位符
1 密码加密原则(续)
1.1 盐值的优化
为了进一步保障密码安全,可以考虑使用随机的盐值,但是,需要注意,随机的盐值必须保存下来,否则,当“注册”时使用随机盐进行编码得到密文,后续“登录”时在无法得到相同盐值的情况下,无法编码得到相同的密文,会导致注册的账号无法经过密码验证来登录!
示例:
@Test
void encode() {
String salt = UUID.randomUUID().toString()
.replace("-", ""); // 盐值
String rawPassword = "123456";
String encodedPassword = DigestUtils.md5DigestAsHex(
(rawPassword + salt).getBytes());
System.out.println("盐值:" + salt);
System.out.println("原文:" + rawPassword);
System.out.println("密文:" + (salt + encodedPassword));
// 5571de817ae548439e21b25c51dc355d8dcf37525ca32a3916b56b7db1f15051
// 1451c0a6320d4aacbd2453862a354e7c7cd8c5ad0d09027f0fc64f0ce52cf2df
}
@Test
void matches() {
String rawPassword = "123456";
String dbPassword = "1451c0a6320d4aacbd2453862a354e7c7cd8c5ad0d09027f0fc64f0ce52cf2df";String salt = dbPassword.substring(0, 32);
String encodedPassword = DigestUtils.md5DigestAsHex(
(rawPassword + salt).getBytes());
System.out.println("盐值:" + salt);
System.out.println("原文:" + rawPassword);
System.out.println("密文:" + (salt + encodedPassword));
System.out.println("验证结果:" + dbPassword.equals(salt + encodedPassword));
}
但是,以上做法仍无法抵御“穷举式的暴力破解”,在这种破解手段面前,是完全无视加密时使用的算法的,而是直接通过你设计算法,一个个的去尝试,直至“试”正确的原始密码。
针对暴力破解,最有效的手段就是:验证码、对恶意访问的客户端实施禁止访问的机制(例如封IP等、封账号)。
另外,还可以使用一些更加安全的算法,来避免被暴力破解!有些用于处理密码加密的算法被刻意的设计成“非常慢”的算法!例如`BCrypt`算法就是非常慢的(个人电脑,每秒13次左右):
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();@Test
void encode() {
String rawPassword = "123456";
System.out.println("原文:" + rawPassword);String encodedPassword = passwordEncoder.encode(rawPassword);
System.out.println("密文:" + encodedPassword);// 密文:$2a$10$Ns6YHxeVxdG1aFLkSX/0e.xT9QMKte/wZBIv.fZ/mhNxP7K8RvzPC
// 密文:$2a$10$TpWV/CzbsTP/nYvmjH3BjuXBjnZUHJ6dkWO8/0CORsXFzIQUojw9K
// 密文:$2a$10$7LIZM.IxoUy9e1NSkqHEF.7SkeRbvNlNtnlRqY6rUssVNa1T36KAm
// 密文:$2a$10$6c7EETFK/iRlt3iAxBhsZu/OTFrSo8RZWzGPRJVuCHGek2ms4M71S
// 密文:$2a$10$LOXtGYZF.MYlrbcDlJ/Q4Okj6VXOV9V3dHNtaAxEbXcZzG2K1Dha2
// 密文:$2a$10$p8gHsRqNUXUE1l4JFHH.4uDkpu7WArXpPiU4Dxhf2tv.o3BK7PBem
// 密文:$2a$10$VHAAkbg4cbTfzvP6WiMH8eo95f2j3VKlDtD4t.SmtOjucOIDsuZj2
// 密文:$2a$10$Pnsmkc8jV.6sILuO4hfb9ui7rpHx2Qk/cj5YBr1YIr.jiRCuKpJ2i
// 密文:$2a$10$l56hXamC5cGxBsYBcOHfg.g1XbVM21YfWq.4oWm2PUypTfgRrv3O.
// 密文:$2a$10$iyyAWxSQnG8DNd8qbMon0.gCxy5c7uzxBP3tZOFPIcFg5LxcunIEC
}
@Test
void matches() {
String rawPassword = "123456";
System.out.println("原文:" + rawPassword);String encodedPassword = "$2a$10$7LIZM.IxoUy9e1NSkqHEF.7SkeRbvNlNtnlRqY6rUssVNa1T36KAm";
System.out.println("密文:" + encodedPassword);System.out.println("验证结果:" + passwordEncoder.matches(rawPassword, encodedPassword));
}
提示:`BCrypt`算法本身也是使用了随机的盐值,且盐值是密码的一部分,所以,并不影响其验证密码。
基于`BCrypt`算法的特性(随机盐、非常慢),是目前主流的用于对密码进行加密并用于存储的算法!
提示:`BCrypt`算法本身已经非常安全,通常并不需要使用额外的处理机制,当然,如果你还不放心,也可以继续加盐,或混合其它算法再次处理!通常,没有这个必要性!
1.2 Mybatis中的占位符
在使用Mybatis框架实现数据库编程时,在SQL语句的参数可以使用`#{}`的占位符来表示,例如:
```sql
DELETE FROM pms_album WHERE id=#{id}
```
其实,在`#{}`的大括号中的名称是可以完全随意填写的!例如写成`#{id}`,或`#{abcdefg}`,或`#{0}`等等,都是可以正确执行的!
之所以`#{}`中的名称可以随意填写,是因为以上SQL语句只有1个参数,Mybatis会自动的找到这个参数值用于执行SQL语句,无论名称是什么,都不会影响Mybatis找到这个参数值!
在**非Spring Boot项目**中,如果抽象方法的参数不只1个,默认情况下,Mybatis无法识别任何参数的名称,例如配置为:
```java
int updateNameById(Long id, String name);
```
```xml
<update id="updateNameById">
update
pms_album
set
name=#{name}
where
id=#{id}
</update>
```
执行时将出现错误,如下所示:
Caused by: org.apache.ibatis.binding.BindingException: Parameter 'name' not found. Available parameters are [arg1, arg0, param1, param2]
之所以出现这个错误,是因为所有`.java`文件在执行之前都需要被编译为`.class`文件,最终执行的是`.class`文件,而默认的编译行为会**丢弃所有局部的量(包含局部变量、方法的参数)的名称**!也就是说,以上代码在编译到`.class`文件中后,根本没有`id`、`name`这样的参数名称!
根据以上提示`Available parameters are [arg1, arg0, param1, param2]`,此时,只能使用`arg0`表示第1个参数,使用`arg1`表示第2个参数,或者,使用`param1`表示第1个参数,使用`param2`表示第2个参数……即`arg`开头是使用`0`开始顺序编号的,`param`开头是使用`1`开始顺序编号的,如果你的抽象方法有更多参数,也可以继续编号下去(无视以上信息中是否提示了)。
例如配置为:
```xml
<update id="updateNameById">
update
pms_album
set
name=#{arg1}
where
id=#{arg0}
</update>
```
在Spring Boot中,干预了编译过程,保留了参数名称,所以,在配置SQL语句时,可以在`#{}`中写参数的名称,例如:
```xml
<update id="updateNameById">
update
pms_album
set
name=#{name}
where
id=#{id}
</update>
```
个人主页:居然天上楼
感谢你这么可爱帅气还这么热爱学习~~
人生海海,山山而川
你的点赞👍 收藏⭐ 留言📝 加关注✅
是对我最大的支持与鞭策