使用md5+salt+hash散列查询

一.说明

1.分析

通过MD5+salt+hash散列进行用户登录查询。

重点:(1)加密存储到数据库(2)验证登录用户信息和数据库信息是否一致

2.目录结构

图片

二.范例

1.调用类

(1)代码块

package com.fengmo;
import com.relam.CustomerMD5;
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;
/**
 * 测试:使用MD5+salt+hash散列的业务逻辑和使用
 */
public class TestCustomerMD5 {
    public static void main(String[] args) {
        //1.创建安全管理器
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //2.1创建realm
        CustomerMD5 customerMD5 = new CustomerMD5();
        //2.2创建hash凭证管理器
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //2.3设置加密的算法是MD5
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        //2.4设置散列次数
        hashedCredentialsMatcher.setHashIterations(1024);
        //2.4设置realm为hash凭证管理器【以上为管理器的配置】
        customerMD5.setCredentialsMatcher(hashedCredentialsMatcher);
        //2.5注入realm
        securityManager.setRealm(customerMD5);
        //3.将安全管理器注入到安全工具
        SecurityUtils.setSecurityManager(securityManager);
        //4.通过subject获取容器对象
        Subject subject = SecurityUtils.getSubject();
        //5.创建令牌
        UsernamePasswordToken token = new UsernamePasswordToken("xiaochen", "123");
        //6.认证
        try{
            subject.login(token);
            System.out.println("没有异常,则登录成功");
        }catch (UnknownAccountException e){     //用户名不存在
            e.printStackTrace();
            System.out.println("用户名错误");
        }catch (IncorrectCredentialsException e2){  //密码错误
            e2.printStackTrace();
            System.out.println("密码错误");
        }
    }
}

(2)范例

图片

图片

2.md5加密类【用于注册用户时存储密码进行加密】

(1)代码块

package com.md5;
import org.apache.shiro.crypto.hash.Md5Hash;
/*
    MD5算法:
        1.作用:一般用于加密或者签名(校验和)
        2.特点:MD5算法不可逆,如何内容相同无论执行多少次md5生成结果始终是一致
        3.生成结果:始终是一个16进制32位长度字符串
        4.加密时选择MD5+Salt(盐)
 */
public class MD5Demo {
    public static void main(String[] args) {
        //1.创建MD5算法
        Md5Hash md5Hash = new Md5Hash();
        //1.2使用byte【】数组形式的参数加密
        md5Hash.setBytes("123".getBytes());
        //1.3查看加密的结果
        String hex = md5Hash.toHex();   //返回加密后的字符串
        System.out.println("这是错误的密码算法"+hex);
        //以上的错误加密写法
        //正确写法一【不加salt(盐)的算法,不推荐】
        //2.1.创建MD5算法
        Md5Hash md5Hash2 = new Md5Hash("123");  //构造参数存储需要加密的明文字符串
        //2.2获取加密后的结果
        //存储数据库时就用md5Hash2.toHex()
        System.out.println("这是正确的密码算法(不加salt)"+md5Hash2.toHex());
        //正确写法二【加salt(盐)的算法,推荐】
        //3.1使用md5+salt处理
        Md5Hash md5Hash3 = new Md5Hash("123","X0*7ps"); //salt可以随意写
        //3.2获取加密后的结果
        //存储数据库时就用md5Hash2.toHex()
        System.out.println("这是正确的密码算法(加salt)"+md5Hash3.toHex());
        //正确写法三 MD5 + salt + hash散列
        //4.1使用md5+salt+hash散列
        Md5Hash md5Hash4 = new Md5Hash("123","X0*7ps",1024);
        //4.2获取加密后的结果
        //存储数据库时就用md5Hash2.toHex()
        System.out.println("这是正确的密码算法(加salt加hash散列)"+md5Hash4.toHex());
    }
}

(2)范例

图片

图片

3.认证类【用于登录用户验证用户信息】

(1)代码块

package com.relam;
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;
/**
 * 自定义realm实现 + MD5 + salt + hash散列
 * 将认证/获取数据的来源转为数据库的实现
 */
public class CustomerMD5 extends AuthorizingRealm {
    //这是授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }
    //这是认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //获取身份信息【获取用户名】
        String principal = (String)token.getPrincipal();
        //根据用户名查询数据库
        if("xiaochen".equals(principal)){   //xiaochen以后是从数据库进行获取
            //明文存储
            //return new SimpleAuthenticationInfo(principal,"123",this.getName());
            //md5算法存储
            //return new SimpleAuthenticationInfo(principal,"202cb962ac59075b964b07152d234b70",this.getName());
            //参数一是身份信息,参数二是数据库获取的密码【MD5+salt】,参数三是salt,参数四是realm的名称
            //return new SimpleAuthenticationInfo(principal, "8a83592a02263bfe6752b2b5b03a4799", ByteSource.Util.bytes("X0*7ps"), this.getName());
            //参数一是身份信息,参数二是数据库获取的密码【MD5+salt+散列】,参数三是salt,参数四是realm的名称
            return new SimpleAuthenticationInfo(principal,"e4f9bf3e0c58f045e62c23c533fcf633", ByteSource.Util.bytes("X0*7ps"),this.getName());
        }
        return null;
    }
}

(2)范例

图片

图片

三.源码

shiro2.rar

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值