散列算法
散列算法一般用于生成一段文本的摘要信息,将内容可以生成摘要,无法将摘要转成原始内容。
- 散列算法不可逆
- 散列算法常用于对密码进行散列
- 常用的散列算法有 MD5、SHA
一般散列算法需要提供一个 salt (盐) 与原始内容生成摘要信息,这样做的目的是为了安全性
比如:111111 的 md5值是:96e79218965eb72c92a549dd5a330112,
拿着 96e79218965eb72c92a549dd5a330112 去md5破解网站很容易进行破解
如果要是对111111和salt(盐,一个随机数)进行散列,这样虽然密码都是111111,但是 加不同的盐会生成不同的散列值。
@Test
public void test() { //md5加密,不加盐
String password_md5 = new Md5Hash("111111").toString();
System.out.println("password_md5=" + password_md5);
//md5加密,加盐 一次散列
String password_md5_salt_1 = new Md5Hash("111111", "imcode", 1).toString();
System.out.println("password_md5_salt_1=" + password_md5_salt_1);
//两次散列相当于md5(md5())
String password_md5_salt_2 = new Md5Hash("111111", "imcode", 2).toString();
System.out.println("password_md5_salt_2=" + password_md5_salt_2);
//使用SimpleHash
String password_md5_simpleHash = new SimpleHash("MD5", "111111", "imcode", 2).toString();
System.out.println("password_md5_simpleHash=" + password_md5_simpleHash);
}
加密工具类
public class MD5Util {
// 散列次数
private static int hashIterations = 3;
private static String salt = "ak47";
/**
* md5加密工具类
* @param source
* @param salt
* @return
*/
public static String md5(String source, String salt) {
return new Md5Hash(source, salt, hashIterations).toString();
}
public static String md5_salt(String source) {
return new Md5Hash(source, salt, hashIterations).toString();
}
}
Realm
public class ShiroRealm extends AuthorizingRealm {
/**
* 登录认证
*
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
// 1.获取用户输入的用户名
String username = token.getUsername();
// 2.获取用户输入的密码
String password = new String(token.getPassword());
// 3.根据用户名去DB查询对应的用户信息,密码为加密后的密文
User user = new User("admin", "3635b070bdf50a94f350c1d050ab1b61", 0);
//User user = new User("admin", "123456", 0);
if (!user.getUsername().equals(username)) {
throw new UnknownAccountException("用户名不存在");
}
if (!user.getPassword().equals(password)) {
throw new CredentialsException("密码错误");
}
if (user.getStatus() == 1) {
throw new DisabledAccountException("账号被禁用");
}
if (user.getStatus() == 2) {
throw new LockedAccountException("账号被锁定");
}
System.out.println("认证成功...");
// 创建简单认证信息对象
SimpleAuthenticationInfo info =
new SimpleAuthenticationInfo(token.getPrincipal(), token.getCredentials(), getName());
return info;
}
/**
* 授权
* 将认证通过的用户的角色和权限信息设置到对应用户主体上
*
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = principals.getPrimaryPrincipal().toString();
//模拟从数据库获取当前用户的角色 通过用户名查询该用户拥有的角色名称
Set<String> roleNameSet = new HashSet<>();
roleNameSet.add("系统管理员");
//roleNameSet.add("系统运维");
//模拟从数据库获取当前用户的权限 通过用户名查询该用户拥有的权限名称
Set<String> permissionNameSet = new HashSet<>();
permissionNameSet.add("sys:user:list"); // 查看列表
permissionNameSet.add("sys:user:info"); // 查看用户详情
permissionNameSet.add("sys:user:create");// 创建用户
permissionNameSet.add("sys:user:update");// 修改用户
permissionNameSet.add("sys:user:delete");// 删除用户
// 简单授权信息对象,对象中包含用户的角色和权限信息
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(roleNameSet);
info.addStringPermissions(permissionNameSet);
System.out.println("授权完成....");
return info;
}
}
测试:
@Test
public void test04() {
// 模拟从客户端接收到用户登录输入的用户名和密码(明文)
String username = "admin";
String password = "123456";
// 将明文的密码加密成密文
String salt = MD5Util.md5_salt(username + password);
password = MD5Util.md5(password, salt);
// 登录认证
ShiroUtil.login(username, password);
}
控制台打印:
认证成功...
[DEBUG] Looked up AuthenticationInfo [admin] from doGetAuthenticationInfo
[DEBUG] AuthenticationInfo caching is disabled for info [admin]. Submitted token: [org.apache.shiro.authc.UsernamePasswordToken - admin, rememberMe=false].
[DEBUG] Performing credentials equality check for tokenCredentials of type [[C and accountCredentials of type [[C]
[DEBUG] Both credentials arguments can be easily converted to byte arrays. Performing array equals comparison
[DEBUG] Authentication successful for token [org.apache.shiro.authc.UsernamePasswordToken - admin, rememberMe=false]. Returned account [admin]
[DEBUG] No sessionValidationScheduler set. Attempting to create default instance.
[INFO] Enabling session validation scheduler...
[DEBUG] Creating new EIS record for new session instance [org.apache.shiro.session.mgt.SimpleSession,id=null]