Shiro___加密加盐迭代

简单的模拟账号密码登入,为了简便就不去数据库真实的查询了

这里先使用MD5加盐迭代加密,算出我们的密码加密结果
MD5是不可逆的,单向加密,所以我们需要对原始数据进行加密后与加密的数据对比,而不是去解密

package com.test;

import org.apache.shiro.crypto.hash.Md5Hash;
/**
 * 对123456加密,
 * 盐值(salt):zsl
 * 迭代次数:6
 * 加密结果:70fc2a964652cf72d7f67022a7951e51
 * @author Administrator
 *
 */
public class MD5Test {

    public static void main(String[] args) {
        Md5Hash mdh = new Md5Hash("123456", "zsl", 6);
        System.out.println(mdh);
        //70fc2a964652cf72d7f67022a7951e51
    }
}

自定义的Realm:
认证方法

package com.test;

import java.util.ArrayList;
import java.util.List;

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.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.SimpleByteSource;

public class MyRealm extends AuthorizingRealm{

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 获取当前登录的账号
        Object principal = principals.getPrimaryPrincipal();

        List<String> roleList = new ArrayList<>();
        List<String> psList = new ArrayList<>();
        roleList.add("role1");
        roleList.add("role2");
        roleList.add("role3");

        psList.add("create");
        psList.add("query");
        psList.add("delete");

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        info.addRoles(roleList);
        info.addStringPermissions(psList);

        return info;
    }

    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
        // TODO Auto-generated method stub
        //获取账号信息
        Object principal = arg0.getPrincipal();
        //从数据库等数据源获取数据
        String name = "root";

        if (!name.equals(principal)) {//低质量的匹配认证
            return null;
        }
        //根据账号去数据库查询出密码
        //经过加密加盐迭代后的密码,这里模拟从数据库查询出了已加密的结果
        String pwd = "70fc2a964652cf72d7f67022a7951e51";

        //我们知道自定义的Realm是不验证密码的,实际验证密码的是AuthenticatingRealm中的AuthenticationInfo方法
        //这里的SimpleAuthenticationInfo就是封装好的验证密码的方法
        //这里提供了new SimpleByteSource("zsl"),zsl是盐值,而迭代次数在ini中
        AuthenticationInfo  info = new SimpleAuthenticationInfo(principal,pwd,new SimpleByteSource("zsl"),  "MyRealm");

        return info;
    }

}

在没有整合其他框架,如Spring前,我们这里配置ini文件来代替xml以及数据库
Shiro.ini:

[main] #定义凭证匹配器 credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher #散列算法 credentialsMatcher.hashAlgorithmName=md5 #散列次数 credentialsMatcher.hashIterations=1 #将凭证匹配器设置到realm customRealm=com.dpb.realm.MyRealm customRealm.credentialsMatcher=$credentialsMatcher securityManager.realms=$customRealm

测试:

public class Test {
    public static void main(String[] args) {
        // 获取SecurityManagerFactory对象
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        // 根据工厂对象获取SecurityManager对象
        SecurityManager manager = factory.getInstance();
        // 将SecurityManager添加到运行环境中
        SecurityUtils.setSecurityManager(manager);

        // 获取Subject对象
        Subject subject = SecurityUtils.getSubject();
        // 获取对应的认证令牌
        AuthenticationToken token = new UsernamePasswordToken("root", "123456") ;
        // 做登录认证
        try {
            subject.login(token);
            System.out.println("登录成功....");
        } catch (UnknownAccountException e) {
            System.out.println("账号错误...");
        } catch (IncorrectCredentialsException e) {
            System.out.println("密码错误...");
        }
        System.out.println(subject.isAuthenticated());
}
}

这里是类似于把密码加密加盐迭代后的结果存到数据库,然后客户端请求来的密码是没有加密加盐迭代的,我们需要对它也同样的进行加密加盐迭代,与通过账号到数据库查询出来的密码进行比对。我们知道自定义的Realm是不验证密码的,实际验证密码的是AuthenticatingRealm中的AuthenticationInfo方法去验证密码,所以我们这里自定义的Realm继承AuthorizingRealm重写了doGetAuthenticationInfo方法,这样我们就可以对我们的账号和密码进行相关业务操作。

原文地址:https://www.cnblogs.com/zhangsonglin/p/10983071.html

时间: 2024-10-08 22:22:51

Shiro___加密加盐迭代的相关文章

php登录加密加盐

1         背景 涉及身份验证的系统都需要存储用户的认证信息,常用的用户认证方式主要为用户名和密码的方式,为了安全起见,用户输入的密码需要保存为密文形式,可采用已公开的不可逆的hash加密算法,比如SHA256, SHA512, SHA3等,对于同一密码,同一加密算法会产生相同的hash值,这样,当用户进行身份验证时,也可对用户输入的明文密码应用相同的hash加密算法,得出一个hash值,然后使用该hash值和之前存储好的密文值进行对照,如果两个值相同,则密码认证成功,否则密码认证失败.

MD5加密加盐

Java实现MD5的随机加盐加密,这样以来就很难解密了,必须使用原密码才能正常的登录系统了,以下为Java实现的MD5随机加盐加密,以及使用Apache的Hex类实现Hex(16进制字符串和)和字节数组的互转: 1 package com.dq.online.onlinezuul.util; 2 3 import org.apache.commons.codec.binary.Hex; 4 5 import java.security.MessageDigest; 6 import java.u

密码加盐

import java.security.MessageDigest;import java.util.Random; import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin; /** * @fileName Md5PasswordUtil.java * @Description 明文密码加密加盐操作 * 1:生成加密密码:首先使用randomSalt获取随机盐值,并保存;再将随机盐值和明文密码传入generate生成加密密文

MD5 加密 以及 加盐加密

这是MD5加密 - (NSString *)MD5Hash { const char *cStr = [self UTF8String]; unsigned char result[16]; CC_MD5(cStr, strlen(cStr), result); NSString * string= [NSString stringWithFormat: @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"

一种简单的md5加盐加密的方法(防止彩虹表撞库)

md5加密(或者说摘要算法)大家都很熟悉了 就不解释了 现在很多数据库设计都喜欢用单向加密的方式保存密码,验证时对提交的密码再次加密之后做密文对比 /// <summary> 使用MD5加密 /// </summary> /// <param name="input">加密字符串</param> /// <remarks>2015.08.26</remarks> public static Guid ToMD5(s

密码的加盐加密

我们 所 使用密码的加密方式 大多为md5 加密  但是一些不法分子 利用 云计算 分布式计算 可以暴力破解我们的密码 我们通过 加入盐值的方式 加密 密码使得密码 不会被轻易破解 1 //对密码进行加盐加密 2 $password = $this->data['password']; 3 //生成盐值 随机生成几个字符串 4 $altToken = md5(String::randString(10)); 5 //加入盐值 6 $password = md5($password.$altTok

加盐加密salt

加盐加密是一种对系统登录口令的加密方式,它实现的方式是将每一个口令同一个叫做”盐“(salt)的n位随机数相关联. 加盐加密是一种对系统登录口令的加密方式,它实现的方式是将每一个口令同一个叫做”盐“(salt)的n位随机数相关联.无论何时只要口令改变,随机数就改变.随机数以未加密的方式存放在口令文件中,这样每个人都可以读.不再只保存加密过的口令,而是先将口令和随机数连接起来然后一同加密,加密后的结果放在口令文件中. 为什么需要加盐加密? 普通的加密方式不够安全吧,加点盐掺杂在需要加密的字符串中,

MD5加盐加密

package com.chauvet.utils; import java.security.NoSuchAlgorithmException;import java.util.Random; /*** * MD5 * @author WXW * */public class MD5Util { private final String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_."

[转]加盐hash保存密码的正确方式

0x00 背景 大多数的web开发者都会遇到设计用户账号系统的需求.账号系统最重要的一个方面就是如何保护用户的密码.一些大公司的用户数据库泄露事件也时有发生,所以我们必须采取一些措施来保护用户的密码,即使网站被攻破的情况下也不会造成较大的危害.保护密码最好的的方式就是使用带盐的密码hash(salted password hashing).对密码进行hash操作是一件很简单的事情,但是很多人都犯了错.接下来我希望可以详细的阐述如何恰当的对密码进行hash,以及为什么要这样做. 0x01 重要提醒