美文网首页程序员IT@程序员猿媛程序员
shiro散列算法密码加盐测试精讲篇

shiro散列算法密码加盐测试精讲篇

作者: 您好简书 | 来源:发表于2019-06-16 12:52 被阅读5次

    散列算法

    通常需要对密码 进行散列,常用的有md5、sha,

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

    如果进行密码对比时,使用相同 方法,将原始密码+盐进行散列,进行比对。

    shiro-realm-md5.ini

    [main]
    #\u5b9a\u4e49\u51ed\u8bc1\u5339\u914d\u5668
    credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
    #\u6563\u5217\u7b97\u6cd5
    credentialsMatcher.hashAlgorithmName=md5
    #\u6563\u5217\u6b21\u6570
    credentialsMatcher.hashIterations=1
    
    #\u5c06\u51ed\u8bc1\u5339\u914d\u5668\u8bbe\u7f6e\u5230realm
    customRealm=cn.itcast.shiro.realm.CustomRealmMd5
    customRealm.credentialsMatcher=$credentialsMatcher
    securityManager.realms=$customRealm
    
    

    自定义CustomRealmMd5.java

    package cn.itcast.shiro.realm;
    
    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;
    
    /**
     * 
     * <p>
     * Title: CustomRealm
     * </p>
     * <p>
     * Description:自定义realm
     * </p>
     * <p>
     * Company: www.itcast.com
     * </p>
     * 
     * @author 传智.燕青
     * @date 2015-3-23下午4:54:47
     * @version 1.0
     */
    public class CustomRealmMd5 extends AuthorizingRealm {
    
        // 设置realm的名称
        @Override
        public void setName(String name) {
            super.setName("customRealmMd5");
        }
    
        // 用于认证
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(
                AuthenticationToken token) throws AuthenticationException {
    
            // token是用户输入的
            // 第一步从token中取出身份信息
            String userCode = (String) token.getPrincipal();
    
            // 第二步:根据用户输入的userCode从数据库查询
            // ....
    
            // 如果查询不到返回null
            // 数据库中用户账号是zhangsansan
            /*
             * if(!userCode.equals("zhangsansan")){// return null; }
             */
    
            // 模拟从数据库查询到密码,散列值
            String password = "f3694f162729b7d0254c6e40260bf15c";
            // 从数据库获取salt
            String salt = "qwerty";
            //上边散列值和盐对应的明文:111111
    
            // 如果查询到返回认证信息AuthenticationInfo
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
                    userCode, password, ByteSource.Util.bytes(salt), this.getName());
    
            return simpleAuthenticationInfo;
        }
    
        // 用于授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(
                PrincipalCollection principals) {
            // TODO Auto-generated method stub
            return null;
        }
    
    }
    
    
    

    测试

    // 自定义realm实现散列值匹配
        @Test
        public void testCustomRealmMd5() {
    
            // 创建securityManager工厂,通过ini配置文件创建securityManager工厂
            Factory<SecurityManager> factory = new IniSecurityManagerFactory(
                    "classpath:shiro-realm-md5.ini");
    
            // 创建SecurityManager
            SecurityManager securityManager = factory.getInstance();
    
            // 将securityManager设置当前的运行环境中
            SecurityUtils.setSecurityManager(securityManager);
    
            // 从SecurityUtils里边创建一个subject
            Subject subject = SecurityUtils.getSubject();
    
            // 在认证提交前准备token(令牌)
            // 这里的账号和密码 将来是由用户输入进去
            UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",
                    "222222");
    
            try {
                // 执行认证提交
                subject.login(token);
            } catch (AuthenticationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
            // 是否认证通过
            boolean isAuthenticated = subject.isAuthenticated();
    
            System.out.println("是否认证通过:" + isAuthenticated);
    
        }
    

    散列是什么?

    package cn.itcast.shiro.authentication;
    
    import org.apache.shiro.crypto.hash.Md5Hash;
    import org.apache.shiro.crypto.hash.SimpleHash;
    
    /**
     * 
     * <p>Title: MD5Test</p>
     * <p>Description: </p>
     * <p>Company: www.itcast.com</p> 
     * @author  传智.燕青
     * @date    2015-3-23下午5:14:47
     * @version 1.0
     */
    public class MD5Test {
        
        public static void main(String[] args) {
            
            //原始 密码 
            String source = "111111";
            //盐
            String salt = "qwerty";
            //散列次数
            int hashIterations = 2;
            //上边散列1次:f3694f162729b7d0254c6e40260bf15c
            //上边散列2次:36f2dfa24d0a9fa97276abbe13e596fc
            
            
            //构造方法中:
            //第一个参数:明文,原始密码 
            //第二个参数:盐,通过使用随机数
            //第三个参数:散列的次数,比如散列两次,相当 于md5(md5(''))
            Md5Hash md5Hash = new Md5Hash(source, salt, hashIterations);
            
            String password_md5 =  md5Hash.toString();
            System.out.println(password_md5);
            //第一个参数:散列算法 
            SimpleHash simpleHash = new SimpleHash("md5", source, salt, hashIterations);
            System.out.println(simpleHash.toString());
            
            
            
        }
    
    }
    
    
    

    相关文章

      网友评论

        本文标题:shiro散列算法密码加盐测试精讲篇

        本文链接:https://www.haomeiwen.com/subject/caawfctx.html