散列算法

  散列算法一般用于生成一段文本的摘要信息,散列算法不可逆,将内容可以生成摘要,无法将摘要转成原始内容。散列算法常用于对密码进行散列,常用的散列算法有MD5SHA

  一般散列算法需要提供一个salt(盐)与原始内容生成摘要信息,这样做的目的是为了安全性,比如:111111md5值是:96e79218965eb72c92a549dd5a330112,拿着“96e79218965eb72c92a549dd5a330112”去md5破解网站很容易进行破解,如果要是对111111salt(盐,一个随机数)进行散列,这样虽然密码都是111111加不同的盐会生成不同的散列值。

Md5散列源码

散列示例

public class Md5Util {
    private static final String PASSWROD="111111"; //要加密的明文
    private static final String SALT = "tdit";//
    private static final int HASHITERATIONS=2;//加密次数
    
    @Test
    public void md5Test() {
        //96e79218965eb72c92a549dd5a330112
    Md5Hash md5Hash =     new Md5Hash(Md5Util.PASSWROD);
    String passwordMd5 = md5Hash.toString();
    System.out.println(passwordMd5);
    }
    
    /**
     * md5加Salt加密
     */
    @Test
    public void md5SaltTest() {
        //5969345e633667bbf5f5102c179a2d67
    Md5Hash md5Hash =     new Md5Hash(PASSWROD,SALT);
    String passwordMd5 = md5Hash.toString();
    System.out.println(passwordMd5);
    }
    

    /**
     * md5加Salt 散列次数 
     */
    @Test
    public void md5SaltIterationsTest() {
        //111111加盐散列2次: 21f2a979da49e3fa35dc6a16467b1483
        //simpleHash   : 21f2a979da49e3fa35dc6a16467b1483
    Md5Hash md5Hash =     new Md5Hash(PASSWROD,SALT,HASHITERATIONS);
    String passwordMd5 = md5Hash.toString();
    System.out.println(passwordMd5);
    }
    
    @Test
    public void SimpleHashSaltIterationsTest() {
        String string = new SimpleHash("md5",PASSWROD,SALT,HASHITERATIONS).toString();        
        System.out.println(string);
    }
}

 

在realm中使用

  实际应用是将盐和散列后的值存在数据库中,自动realm从数据库取出盐和加密后的值由shiro完成密码校验。

自定义realm

  

@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token){
        //获取认证凭证
         UsernamePasswordToken upToken = (UsernamePasswordToken) token;
            String username = upToken.getUsername();

            // Null username is invalid
            if (username == null) {
                throw new AccountException("账号不能为空");
            }

            SimpleAuthenticationInfo info = null;
            
            //模拟数据库获取数据
            Map<String,Object> data = new HashMap<String,Object>();
            //原始密码111111
            //md5加盐散列2次密码21f2a979da49e3fa35dc6a16467b1483
            data.put("zhangsan", "21f2a979da49e3fa35dc6a16467b1483");
            data.put("lisi", "21f2a979da49e3fa35dc6a16467b1483");
            data.put("wang", "21f2a979da49e3fa35dc6a16467b1483");
            //通过数据库获取username的信息
            Object userPassword = data.get(username);
            if (userPassword ==null) {
                return null;
            }
            
            if (userPassword == null) {
                throw new UnknownAccountException("密码错误");
            }
            info = new SimpleAuthenticationInfo(username, userPassword,ByteSource.Util.bytes("tdit"), getName());
        
            return info;
    }

realm配置

 默认凭证匹配器进行密码匹配的源码流程

现在我们使用md5进行加密,所以需要指定(配置)使用的匹配器

在这里可以直接使用md5

配置shiro-cryptography.ini

[main]
#定义凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#散列算法
credentialsMatcher.hashAlgorithmName=md5
#散列次数
credentialsMatcher.hashIterations=2

#将凭证匹配器设置到realm
customRealm=com.td.shiro.realm.CustomRealmMd5
customRealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$customRealm
原文地址:https://www.cnblogs.com/lldsgj/p/10789361.html