Md5+salt实现用户加密
Posted 健康平安的活着
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Md5+salt实现用户加密相关的知识,希望对你有一定的参考价值。
一.md5
1.1 作用
一般用来进行加密或者签名
特点:md5内容不可逆,相同的内容不论执行多少次,md5加密算法生成的结果都是一致的。
结果:生成的结果是一个32位的16进制字符串。
二 md5+salt
salt说白了就是随机的字符串
2.1 md5+salt的使用
注册时md5(输入明文密码+随机盐字符串)生成加密密码p1,随机盐字符串r,都存储到数据库中。
登录时通过用户名查询该用户对应的加密密码p1和随机盐字符串r,按照注册时生成的规则:md5(输入明文密码+随机盐字符串)=p2,
这次登录生成的新的加密字符串p2和从数据库查询出的加密字符串p1进行比较判断。相同则密码正确,否则错误。
三 md5+salt+hash散列案例
3.1 加密
package com.shiro.ljf.demo.test;
import org.apache.shiro.crypto.hash.Md5Hash;
public class TestShiroMD5 {
public static void main(String[] args) {
//创建一个md5算法
// Md5Hash md5Hash = new Md5Hash();
// md5Hash.setBytes("123".getBytes());
// String s = md5Hash.toHex();
// System.out.println(s);
//使用md5
Md5Hash md5Hash = new Md5Hash("123");
System.out.println(md5Hash.toHex());
//使用MD5 + salt处理
Md5Hash md5Hash1 = new Md5Hash("123", "X0*7ps");
System.out.println(md5Hash1.toHex());
//使用md5 + salt + hash散列
Md5Hash md5Hash2 = new Md5Hash("123", "X0*7ps", 1024);
System.out.println(md5Hash2.toHex());
}
}
结果:
202cb962ac59075b964b07152d234b70
8a83592a02263bfe6752b2b5b03a4799
e4f9bf3e0c58f045e62c23c533fcf633
3.2 使用salt+md5+hash散列
package com.shiro.ljf.demo.test;
import com.shiro.ljf.demo.sptshirodemo.shiro.CustomerMd5Realm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;
import java.util.Arrays;
public class TestCustomerMd5RealmAuthenicator {
public static void main(String[] args) {
//创建安全管理器
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
//注入realm
CustomerMd5Realm realm = new CustomerMd5Realm();
//设置realm使用hash凭证匹配器
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
//使用算法
credentialsMatcher.setHashAlgorithmName("md5");
//散列次数
credentialsMatcher.setHashIterations(1024);
realm.setCredentialsMatcher(credentialsMatcher);
defaultSecurityManager.setRealm(realm);
//将安全管理器注入安全工具
SecurityUtils.setSecurityManager(defaultSecurityManager);
//通过安全工具类获取subject
Subject subject = SecurityUtils.getSubject();
//认证
UsernamePasswordToken token = new UsernamePasswordToken("lisi", "123");
try {
subject.login(token);
System.out.println("登录成功");
} catch (UnknownAccountException e) {
e.printStackTrace();
System.out.println("用户名错误");
}catch (IncorrectCredentialsException e){
e.printStackTrace();
System.out.println("密码错误");
}
//授权
if(subject.isAuthenticated()){
}
}
}
自定义reaml:
package com.shiro.ljf.demo.sptshirodemo.shiro;
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.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
/**
* 使用自定义realm 加入md5 + salt +hash
*/
public class CustomerMd5Realm extends AuthorizingRealm {
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String primaryPrincipal = (String) principals.getPrimaryPrincipal();
System.out.println("身份信息: "+primaryPrincipal);
//根据身份信息 用户名 获取当前用户的角色信息,以及权限信息 xiaochen admin user
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//将数据库中查询角色信息赋值给权限对象
simpleAuthorizationInfo.addRole("admin");
simpleAuthorizationInfo.addRole("user");
//将数据库中查询权限信息赋值个权限对象
simpleAuthorizationInfo.addStringPermission("user:*:01");
simpleAuthorizationInfo.addStringPermission("product:create");
return simpleAuthorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//获取身份信息
String principal = (String) token.getPrincipal();
//根据用户名查询数据库
if ("lisi".equals(principal)) {
//参数1: 数据库用户名 参数2:数据库md5+salt之后的密码 参数3:注册时的随机盐 参数4:realm的名字
//用户输入的密码+加上从数据库获取的盐,生成新的加密串,和从数据库加载的串进行比较,这个动作就是在shiro底层自动完成的,这里只需要在
//SimpleAuthenticationInfo设置好对应的参数就行。
return new SimpleAuthenticationInfo(principal,
"e4f9bf3e0c58f045e62c23c533fcf633",
ByteSource.Util.bytes("X0*7ps"),
this.getName());
}
return null;
}
}
3.3 执行结果:
以上是关于Md5+salt实现用户加密的主要内容,如果未能解决你的问题,请参考以下文章