Shiro(四)——Shiro使用MD5散列算法加密

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34598667/article/details/84642279

散列算法

通常要对密码进行散列,常用的有md5、sha等。
对MD5加密,如果知道散列后的值可以通过穷举法,得到MD5密码对应的明文。建议对MD5进行散列时加salt(盐),进行加密相当于对原始密码+盐 进行散列。
正常使用时散列方法:
在程序中对原始密码+盐进行散列,将散列值存储到数据库中,并且还要将盐也要存储在数据库中。
如果进行密码对比时,使用相同方法,将原始密码+盐进行散列,进行对比。

MD5散列测试程序

public class MD5Test {
	public static void main(String[] args) {
		//原始密码
		String source="123456";
		//盐
		String salt="qwerty";
		//散列次数
		int hashInterrations=2;
		/*	方法1:
		 * 第一个参数:明文,原始密码 
		 * 第二个参数:盐,通常使用随机数,这里指定固定字符串
		 * 第三个参数:散列的次数,比如散列两次,相当 于md5(md5(''))
		 */
		Md5Hash md5Hash=new Md5Hash(source, salt, hashInterrations);
		System.out.println(md5Hash);
		//方法2:第一个参数:散列算法 
		SimpleHash sim=new SimpleHash("md5", source, salt,hashInterrations);
		System.out.println(sim);
	}
}

运行测试:

78f50b64a132f209ea77fdeebe501de6
78f50b64a132f209ea77fdeebe501de6

自定义realm支持散列算法

需求:实际开发时realm要进行md5值(明文散列后的值)的对比

@Override
protected AuthenticationInfo doGetAuthenticationInfo(
	AuthenticationToken token) throws AuthenticationException {
	//token是用户输入的
	//1、从token中取出身份信息
	String userCode=(String) token.getPrincipal();
	//2、根据用户输入的userCode从数据库查询
	//假设数据库用户是张三
	//如果查询不到则返回null
	/*if(!userCode.equals("zs")){
	return null;
	}*/
	//模拟从数据库查到密码,散列值(取上面测试生成的散列码)
	String pwd="78f50b64a132f209ea77fdeebe501de6";
	// 模拟从数据库获取salt
	String salt = "qwerty";
	//上边散列值和盐对应的明文:123
	  
	//如果查询到则返回认证信息AuthenticationInfo
	SimpleAuthenticationInfo simpleAuthenticationInfo=new SimpleAuthenticationInfo(
	userCode,pwd,ByteSource.Util.bytes(salt),this.getName());
	return simpleAuthenticationInfo;
}

在realm中配置凭证匹配器

[main]
[main]
#定义凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#散列算法
credentialsMatcher.hashAlgorithmName=md5
#散列次数
credentialsMatcher.hashIterations=2

#自定义realm
customRealm=com.oak.shiro.CustomRealm
#将realm设置到securityManager,相当于Spring注入
securityManager.realms=$customRealm
customRealm.credentialsMatcher=$credentialsMatcher

测试:

@Test
public void testLoginAndLogout(){
	//创建securityManager工厂,通过ini配置文件创建securityManager工厂
	Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:shiro-realm.ini");
	
	//创建SecurityManager
	SecurityManager securityManager=factory.getInstance();
	
	//将securityManager设置到当前运行环境中
	SecurityUtils.setSecurityManager(securityManager);
	
	//从SecurityUtils里边创建一个subject
	Subject subject = SecurityUtils.getSubject();
	//在认证提交前准备token(令牌)
	UsernamePasswordToken token=new UsernamePasswordToken("admin","123");
    
    //执行认证提交--认证失败
    subject.login(token);
    
	//是否认证通过
	boolean isAuthenticated =subject.isAuthenticated();
	System.out.println("是否认证通过:"+isAuthenticated);
	//退出操作
	subject.logout();
	//是否认证通过
	isAuthenticated=subject.isAuthenticated();
	System.out.println("是否认证通过:"+isAuthenticated);
}

测试:

是否认证通过:true
是否认证通过:false

猜你喜欢

转载自blog.csdn.net/qq_34598667/article/details/84642279
今日推荐