Shiro信息加密及简单demo3

Shiro加密了解及demo3演示

解锁:数据加密MD5、加salt、进行hash散列

一、了解MYSQL加密算法

mysql的加密算法:

1.不可逆加密算法:

password ()、md5 ()、encrypt ()、sha5 ()
在这里插入图片描述在这里插入图片描述

2.可逆加密算法:

encode(,)、decode(,):加密解密字符串。函数有个参数:被加密或解密的字符串、作为加密或解密基础的密钥。
encode结果是一个二进制字符串,以BLOB类型存储,加密程度比较弱。
——————————————————
aes_encrypt(,)、aes_decrypt(,):加密解密字符串。函数有个参数:被加密或解密的字符串、作为加密或解密基础的密钥。encode结果是一个二进制字符串,以BLOB类型存储。

加密完成之后可以用to_base64()转成可见字符,然后解密时候用from_base64()转回来.

二、MD5和salt简介和执行流程

2.1 MD5简单介绍

MD5是哈希散列算法,对于MD5而言,有两个特性是很重要的.
第一:明文数据经过散列以后的值是定长的(就是1234经过加密之后, 他的散列之后字符串会变长);
第二:是任意一段明文数据,经过散列以后,其结果必须永远是不变的。
前者的意思是可能存在有两段明文散列以后得到相同的结果。
后者的意思是如果我们散列特定的数据,得到的结果定是相同的。

2.2 salt简单介绍

在家做饭有佐料,在加密领域也有所谓的佐料,只是这是这里的佐料可不是为了味道好,而是为了保护对象的机密性。
往上面撒一些盐,可以有效的解决这个问题,即使用salt加密,它的基本想法是这样的:
1.用户注册时,在密码上撒一些盐。生成一种味道,记住味道。
2.用户再次登陆时,系统在输入的密码上撒盐,闻- -闻,判断是否和原来的味道相同,相同就让你吃饭。
由于验证密码时和最初散列密码时使用相同的盐值,所以salt的存储在数据库。并且这个值是由系统随机产生的,而非硬编码。这就保证了所要保护对象的机密性。

❤❤❤❤❤
以下是图解(图借鉴):
在这里插入图片描述
注册时:
1.用户注册,系统随机产生salt值。
2.将salt值和密码连接起来,生产Hash值。
3.将Hash值和salt值分别存储在数据库中。

在这里插入图片描述
登录时:
1.系统根据用户名找到与之对应的密码Hash。
2.将用户输入密码和salt值进行散列。
3.判断生成的Hash值是否和数据库中Hash相同。

2.3 具体的MD5+salt的具体实现流程

在这里插入图片描述

2.4 ❤使用加密进行demo演示

1.创项目并导shiro-jar包
在这里插入图片描述
2.创SaltTest.java进行测试

public class SaltTest {
    public static void main(String[] args) {
        //****** 一、只是单纯 MD5加密
        //1.实现 MD5加密
        //输出结果和在mysql命令行中的结果一样,说明java中的md5算法和数据库中的md5算法底层原理都是一样--哈希散列
        Md5Hash md5Hash = new Md5Hash("China");
        System.out.println(md5Hash);

        //2.生成两个 MD5码,同样加密
        Md5Hash md5Hash1 = new Md5Hash("China");
        System.out.println(md5Hash1);

        if (md5Hash.equals(md5Hash1)){
            //如果两个明文不一样,就不会打印,道理都懂
            System.out.println("允许登录!!!");
        }
        //缺点很大,因为多个用户可能存在相同的密码

        //****** 二、MD5+salt加密
        System.out.println("MD5+salt方式---------------------------------");
        System.out.println((int) (Math.random() * 10000));
        Md5Hash md5Hash2 = new Md5Hash("China",String.valueOf((int)(Math.random()*10000)));
        //后面参数代表salt,使用random方法随机生成,但是数值为0到1之间的一个小数,所以我这里还需要*10000,然后取整
        System.out.println(md5Hash2);
        //这比第一种好一点,但仍未解决实际问题--因为随机取值,有一个区间,当数量足够大时,就可能出现同样的salt值

        //****** 三、MD5+salt+hash散列
        System.out.println("MD5+salt+hash散列的方式---能解决重复问题");
        System.out.println((int) (Math.random() * 10000));
        Md5Hash md5Hash3 = new Md5Hash("China",String.valueOf((int)(Math.random()*10000)),2048);
        System.out.println(md5Hash3);
        //第三个参数代表我的散列次数,散列次数不一样,salt值最后取得也会不一样。

    }
}

运行结果:
在这里插入图片描述

所以当了解三种加密形式后,需要去用它们,所以创建一个自定义的realm。
3.自创CustomerMDrealm.java

public class CustomerMDRealm extends AuthorizingRealm {
    //授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }
    //认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken YtyToken) throws AuthenticationException {
        System.out.println("已经进入用户认证了-----");
        String name = (String) YtyToken.getPrincipal();//获取前端传入的数据信息
        System.out.println("这是前端传过来的数据:"+name);

        if ("yty".equals(name)){
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
                    name,"ae54a5c026f31ada088992587d92cb3a",//这是China的MD5加密后的信息
                    ByteSource.Util.bytes("String.valueOf((int)(Math.random()*10000)"),this.getName());
                    //ByteSource.Util.bytes后面的参数就是salt值
            return simpleAuthenticationInfo;
        }
        return null;
    }
}

4.创Md5Test.javaj进行测试

public class Md5Test {
    public static void main(String[] args) {
        //1.创建安全管理器
        DefaultSecurityManager ytySecurityManager = new DefaultSecurityManager();

        //这是之前“明文方式”进行认证
//        ytySecurityManager.setRealm(new CustomerMDRealm());//安全管理器设置realm对象
//        SecurityUtils.setSecurityManager(ytySecurityManager);//管理工具设置安全管理器
//        Subject subject = SecurityUtils.getSubject();//管理工具获得主体subject
//        UsernamePasswordToken token = new UsernamePasswordToken("yty", "China");//设置令牌

        //2.使用规则匹配器:让它去匹配我们的 MD5
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("md5");//md5:指定的md5规则
        //3.指定散列次数
        hashedCredentialsMatcher.setHashIterations(2048);
        //4.指定自定义的realm使用的规则是上面的规则匹配器
        CustomerMDRealm customerMDRealm = new CustomerMDRealm();
        customerMDRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        //5.剩下操作就是和明文方式一样的
        //安全管理器设置realm对象
        ytySecurityManager.setRealm(customerMDRealm);
        //管理工具设置安全管理器
        SecurityUtils.setSecurityManager(ytySecurityManager);
        //管理工具获取主体subject
        Subject subject = SecurityUtils.getSubject();
        //设置令牌
        UsernamePasswordToken token = new UsernamePasswordToken("yty","China");

        //6.认证操作
        System.out.println("认证前的操作---------");
        System.out.println(subject.isAuthenticated());

        System.out.println("认证后的操作---------");
        try {
            subject.login(token);
        }catch (UnknownAccountException e){
            System.out.println("用户账号有问题!!!!!");
        }catch (IncorrectCredentialsException e){
            System.out.println("密码错误!!!!!!");
        }
        System.out.println(subject.isAuthenticated());
    }
}

测试结果:
在这里插入图片描述
❤:之所以错误是因为我加了salt(随机0到1的小数乘10000,然后取整),并且散列了2048次。
当只有MD5加密后,就会判断为true。只需要将CustomerMDRealm中的ByteSource.Util.bytes(“String.valueOf((int)(Math.random()*10000)”)淦掉,就取消了加盐,同时Md5Test不能用规则匹配器,用明文方式验证。
淦掉hashedCredentialsMatcher.setHashIterations(2048);就取消了散列。

2.5 老师演示demo

进行加密的操作:
在这里插入图片描述
形成的码:
在这里插入图片描述
使用自定义realm的方式来认证我们的MD5+salt+Hash散列实现:
1.使用CustomerMd5Realm.java类去继承我们的AuthorizingRealm
2.去是实现方法; doGetAuthenticationInfo
在这里插入图片描述
使用自定义的realm进行认证:
在这里插入图片描述
在这里插入图片描述
传入的时候使用MD5加密:
在这里插入图片描述
认证的时候也是通过加密后的就会认证成功:
在这里插入图片描述
在这里插入图片描述
只需要在进行认证的时候指定随机盐进行即可:
在这里插入图片描述
这个地方指定盐值是从数据库中进行取出来的;以及密码都是进行完随机盐之后的值;只需要在这个地方设置之后;传过来的就会是盐之后的MD5码;使用这个随机盐去进行认证数据;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这个存储到里边的时候是根据散列了次数之后的值;就需要进行传入的时候设置他的匹配规则也是散列次数;
在这里插入图片描述
散列次数要对应上:就可以认证
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

11_1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值