MD5加密的特点:
16进制32位,不可逆(通过明文可以获取到它的密文,但是通过密文获取不到对应的明文是什么),相同的数据加密的结果都是一样的
问题:既然MD5加密是不可逆的,为什么网上有md5解谜工具,如何实现的?
网上都是通过穷举法,列举出所有情况 ,一旦密码过于复杂就破解不了
public static void main(String[] args) {
//使用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());
}
注:明文都是123,但是通过三种不同的加密方式结果是不通过的。第三种的安全性相对较高
加密数据的shiro认证流程的验证
/**
* 自定义md5+salt realm
*/
public class CustomerRealm extends AuthorizingRealm {
//授权方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
//认证方法
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String principal = (String) token.getPrincipal();
//实际是通过数据库或到加密的密码和盐,这里仅仅做测试
if("xiaochen".equals(principal)){
String password = "3c88b338102c1a343bcb88cd3878758e";
String salt = "Q4F%";
return new SimpleAuthenticationInfo(principal,password,
ByteSource.Util.bytes(salt),this.getName());
}
return null;
}
public class TestAuthenticatorCusttomerRealm {
public static void main(String[] args) {
//创建securityManager
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
//设置为自定义realm获取认证数据
CustomerRealm customerRealm = new CustomerRealm();
//设置md5加密,修改密码匹配器
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
//设置名称
credentialsMatcher.setHashAlgorithmName("MD5");
credentialsMatcher.setHashIterations(1024);//设置散列次数
customerRealm.setCredentialsMatcher(credentialsMatcher);
defaultSecurityManager.setRealm(customerRealm);
//将安装工具类中设置默认安全管理器
SecurityUtils.setSecurityManager(defaultSecurityManager);
//获取主体对象
Subject subject = SecurityUtils.getSubject();
//创建token令牌
UsernamePasswordToken token = new UsernamePasswordToken("xiaochen", "123");
try {
subject.login(token);//用户登录
System.out.println("登录成功~~");
} catch (UnknownAccountException e) {
e.printStackTrace();
System.out.println("用户名错误!!");
}catch (IncorrectCredentialsException e){
e.printStackTrace();
System.out.println("密码错误!!!");
}
}
}