通常需要对密码 进行散列,常用的有md5、sha,
对md5密码,如果知道散列后的值可以通过穷举算法,得到md5密码对应的明文。
建议对md5进行散列时加salt(盐),进行加密相当 于对原始密码+盐进行散列。
正常使用时散列方法:
在程序中对原始密码+盐进行散列,将散列值存储到数据库中,并且还要将盐也要存储在数据库中。
如果进行密码对比时,使用相同 方法,将原始密码+盐进行散列,进行比对。
md5散列测试程序:
/**
*
* @Title: md5Test
* @Description:测试md5
*/
@Test
public void md5Test() {
// 明文密码
String oldPassword = "111111";
// 盐
String salt = "qwerty";
// 散列次数
int hashIterations = 2;
// 加盐散列一次:f3694f162729b7d0254c6e40260bf15c
// 加盐散列两次:36f2dfa24d0a9fa97276abbe13e596fc
// 第一个参数:明文密码
// 第二个参数:盐,一般使用随机数
// 第三个参数:散列的次数,散列两次相当于:md5(md5("明文密码"))
Md5Hash md5Hash = new Md5Hash(oldPassword, salt, hashIterations);
String newPassword = md5Hash.toString();
System.out.println(newPassword);
// 第一个参数:散列算法
SimpleHash simpleHash = new SimpleHash("md5", oldPassword, salt,
hashIterations);
System.out.println(simpleHash.toString());
}
自定义realm支持散列算法
需求:实际开发时realm要进行md5值(明文散列后的值)的对比。
package com.shiro.test;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
/**
*
* @ClassName: MyRealm
* @Description: 自定义的realm
* @author cheng
* @date 2017-4-5 上午11:09:31
*/
public class MyRealm extends AuthorizingRealm {
/**
* 用于认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
// token是用户输入的
// 1.从token中取出用户信息
String userCode = (String) token.getPrincipal();
// 2.依据用户信息从数据库中查询
// 如果没有查询到,返回null,抛出UnknownAccountException
// ......
// 模拟从数据库中查询得到密码
String oldPassword = "36f2dfa24d0a9fa97276abbe13e596fc";
// 从数据库中得到盐
String salt = "qwerty";
// 上次散列对应的明文为:111111
// 如果查询到了,返回AuthenticationInfo
// 如果密码不匹配,抛出IncorrectCredentialsException
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
userCode, oldPassword, ByteSource.Util.bytes(salt), this
.getName());
return simpleAuthenticationInfo;
}
/**
* 用于授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
// TODO Auto-generated method stub
return null;
}
}
在realm中配置凭证匹配器
# 声明一个 Shiro 已经有的密码匹配的类
hashMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
# 散列的算法
hashMatcher.hashAlgorithmName=md5
# 散列的盐
# hashMatcher.hashSalted=hello
# 散列的次数
hashMatcher.hashIterations=2
# 声明自定义的 Realm 类
myRealm=com.shiro.test.MyRealm
# 将 passwordMatcher 注入到自定义的 Realm 类中
myRealm.credentialsMatcher=$hashMatcher
# 将自定义的 Realm 注入到 securityManager 中
securityManager.realms=$myRealm