关于密码泄漏的历史事件
- 2011年12月,当时最大的程序员社区网站CSDN泄漏用户账号密码,还是明文。
- 2014年,携程网,小米论坛
- 2015年,网易邮箱
以上数据来自网络新闻,不保证准确性,只为了说明密码加密很重要。
账号密码加密为了解决什么问题呢?
- 用户密码明文不可以给任何人看到,包括管理员
- 即使被复制了库也不可以被破解
如何对用户密码进行保护呢?
从用户输入密码时开始,密码就有了,传输,保存到数据库里。这是设置密码。
验证密码也是,从用户输入,到服务器中读取密码。
所以,我们要从用户输入,数据传输,数据存储这些方面去保护好密码。
-
比如说,用户输入,要对用户的输入内容进行保护,用星号掩盖密码。客户端自定义键盘输入。 如果用户的密码比较简单,还得提醒用户使用复杂密码。
-
比如说数据传输,要对数据进行加密后进行传输。
- 比如说数据存储,要对数据加密后进行存储。
加密方式
不能用明文保存密码
前面那些大网站竟然用明文保存密码,这个太不可思议了,而且还是技术社区网站。
所以,不可以使用明文保存密码,这个太愚蠢了。
不可以使用简单的加密
比如说进行简单的转换移位之类的,一旦用字典试破以后,其他密码就全破解了。
不可使用可逆转的加密方式
也就是说,明文可以转密文,密文也可以转明文。这些加密算法不要使用到密码加密上。
使用加盐加密
什么是加盐加密呢?
比如说我们大家都知道MD5加密
比如说我们md5("1234567890"),加密结果为
e807f1fcf82d132f9bb018ca6738a19f
我们加上一个盐值:1jkoajiw!@#
变成了:md5("12345678901jkoajiw!@#")
加密结果:
e82e076b29b6de4224535e4b72b71bb5
当然啦,Hash算法有很多种,比如说MD2、MD4、MD5、HAVAL、SHA-1、SHA256、SHA512、RipeMD、WHIRLPOOL、SHA3、HMAC...
相同内容,同样设备,时间纬度,MD5会比较快一点,SHA-256会慢一点。
生成盐的准则:
- 盐由随机函数生成
- 不同的用户使用不同的盐值
Web开发密码加密
我们使用java开发Web时通常怎么做呢?
不是有框架嘛,对吧!
我们使用SpringSecurity里面就有BCryptPasswordEncoder
里面有个方法叫encode
public String encode(CharSequence rawPassword) {
String salt;
if (strength > 0) {
if (random != null) {
salt = BCrypt.gensalt(strength, random);
}
else {
salt = BCrypt.gensalt(strength);
}
}
else {
salt = BCrypt.gensalt();
}
return BCrypt.hashpw(rawPassword.toString(), salt);
}
连盐都自己搞定了,是不是很方便呢?
ok了,加密码,我们以直接通过encode方法
那么解密呢?
没有解密的,这是不可逆的算法
那怎么办呢?怎么判断用户登陆时密码是否正确呢?
有matches方法嘛
public boolean matches(CharSequence rawPassword, String encodedPassword) {
if (encodedPassword == null || encodedPassword.length() == 0) {
logger.warn("Empty encoded password");
return false;
}
if (!BCRYPT_PATTERN.matcher(encodedPassword).matches()) {
logger.warn("Encoded password does not look like BCrypt");
return false;
}
return BCrypt.checkpw(rawPassword.toString(), encodedPassword);
}
传入用户输入的密码以及数据库中的密码,两者一进行比对,就有一个boolean类型的返回值了
这样子,就可以判断用户的密码是否正确了。
那么我们的博客系统怎么样去整呢?我们下一篇文章再去分析,这里我们了解一下即可。