密码加盐
只对密码进行 md5 加密很容易反推出来,另外两个用户的密码相同时,数据库保存相同的密码,知道一个用户的密码就知道另一个。
解决方法: 在用户的短密码后面加上一段长字符,再计算 md5,这样反推出原始密码就变得非常困难,而且即使两个用户密码相同,数据库保存的密码也不一样。加上的这段长字符,称为盐(Salt),通过这种方式加密的结果,称为加盐 Hash。
使用例子
假设有两个用户 admin 和 abc,密码都为 123456,注册时,盐取用户名 + 一个 MD5 值。 最终计算出来的密码不一样。
package com.example.shiro;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
public class TestPasswordSalt {
public static void main(String[] args) {
String pwd1 = md5("123456", "admin8d78869f470951332959580424d4bf4f");
System.out.println(pwd1); // 密码:d3c59d25033dbf980d29554025c23a75
String pwd2 = md5("123456", "abc0c23e95fd137ea96c4ef24366b7e6f1f");
System.out.println(pwd2); // 密码:ae8bb0dd40e4eddeac081f8e31afdaed
}
public static final String md5(String password, String salt) {
// 加密方式
String hashAlgorithmName = "MD5";
// 盐:相同密码使用不同的盐加密后的结果不同
ByteSource byteSalt = ByteSource.Util.bytes(salt);
// 密码
Object source = password;
// 加密次数
int hashIterations = 2;
SimpleHash result = new SimpleHash(hashAlgorithmName, source, byteSalt, hashIterations);
return result.toString();
}
}
数据库表字段保存
数据库表字段保存见下面表,登录时取用户名 + salt 进行验证:
| username | password | salt |
|---|---|---|
| admin | d3c59d25033dbf980d29554025c23a75 | 8d78869f470951332959580424d4bf4f |
| abc | ae8bb0dd40e4eddeac081f8e31afdaed | 0c23e95fd137ea96c4ef24366b7e6f1f |