背景:

为了密码的安全性,密码要进行加密操作。通常我们使用的散列加密算法,其加密算法是不可逆的,即不能由密文推算出明文,所以即使数据库管理员或者入侵者知道了你存储在数据库里面的密码,也不会知道你真实的密码,这样就保证了你账户的安全性。

然而,单纯的只使用散列加密算法加密,就安全吗?

第一、虽然散列加密算法不能解密,但是却可以碰撞,从而得出原来的明文密码,如果你的密码是 1234 或者 abc 这样简单的密码,即使通过散列加密算法进行加密,也同样是可以被破解出来的。

第二、同一个程序,所使用的加密算法是一致的,假设注册者所拥有的初始密码是一致的,那么,当两个人都没有改变密码的时候,两者存储在数据库里面的密码是一致的。任何人都可以使用 AB 的账号 + 初始密码登录进去。所以使用散列加密算法也不是很安全的,我们希望能有一个标识,在使用散列加密算法加密的时候可以用到这个标识,这个标识应该是唯一的,如用户的 id 或者用户的唯一编号等。这个标识,用专业的术语描述叫做(salt)。

通常我们使用的散列加密有:MD5SHA等。

盐值加密:

举个盐值加密的例子:

用户名:admin

密码:123456

盐值:yanzhi1234

md5 加密:md5(admin123456yanzhi1234)

方便区分这里我加上颜色,我们可以使用 md5 加密这样的字符串,破解难度就显而易见了,当然你可以自由搭配这个加密串,如: md5(adminmd5(123456)yanzhi1234)。也可以多层加密,盐值就是一串随机的字符串,建议每个用户的盐值都不一样,长度自己把控,建议长一些,再迭代加密几次增加破解难度。等到验证的时候以同样的方式加密后对比就可以了。

用户注册:

以我们第二篇的文章为例,如果想要使用 shiro 的盐值加密,则用户存储在数据库表中的密码必须是加密后的数据。先看下面的代码:

@Component
public class InsertUser implements InitializingBean{@AutowiredUserService userService;@Overridepublic void afterPropertiesSet() throws Exception {userService.deleteAll();User user = new User();// 这里我们假设username+"salt"的值为盐值。String salt1 = "zhangsan";String password1 = "123456";String encryp_password1 = MD5Pwd(salt1,password1);user.setUserName(salt1);user.setPassword(encryp_password1);user.setRoleIds("1,2");user.setStatus("1");userService.insert(user);User user2 = new User();String salt2 = "lisi";String password2 = "123456";String encryp_password2 = MD5Pwd(salt2,password2);user2.setUserName(salt2);user2.setPassword(encryp_password2);user2.setRoleIds("2");user2.setStatus("1");userService.insert(user2);User user3 = new User();String salt3 = "wangwu";String password3 = "123456";String encryp_password3 = MD5Pwd(salt3,password3);user3.setUserName(salt3);user3.setPassword(encryp_password3);user3.setRoleIds("1");user3.setStatus("1");userService.insert(user3);}public static String MD5Pwd(String username, String pwd) {// 获取盐值ByteSource salt = ByteSource.Util.bytes(username + "salt");/** SimpleHash()方法是shiro为我们提供的api,对原始密码进行加密。* 第一个参数表示使用MD5方式进行加密* 第二个参数表示原始密码* 第三个参数表示盐值* 第四个参数表示加密的次数* 最后用toHex()方法将加密后的密码转换成String类型* */String md5Pwd = new SimpleHash("MD5",pwd,salt,2).toHex();return md5Pwd;}
}

我们初始化模拟用户注册的场景,将用户的账号和密码存储到数据库表里面,其中用户的密码需要进行加密存储,说白了就是使用 MD5 加密算法然后再加上盐值就可以了,我以前老是不明白这个盐值是不是该存储到数据库表里面,后来翻阅了大量的资料,了解到,这个盐值的组成可以使用用户的 username 或者是其他的字段,然后再拼接个字符串啥的,基本上也就够了。如果你生成了一个随机的字符串作为盐值,或者作为盐值的一部分,则需要将这个随机的字符串存储到数据库表中,要不你校验的时候盐值就拿不到了。

在上面的代码中,我们的创建的盐值由 username+"salt" 构成,并迭代了两次,通过 MD5 加密算法最终得到了加密后的字符串。然后将该字符串存储到数据库的表中。

密码校验:

首先需要在我们的 ShiroConfig 类中配置支持盐值加密的 bean,如下所示:

    // 将自己的验证方式加入容器@Beanpublic CustomRealm myShiroRealm() {CustomRealm customRealm = new CustomRealm();// 告诉realm,使用credentialsMatcher加密算法类来验证密文customRealm.setCredentialsMatcher(hashedCredentialsMatcher());return customRealm;}@Beanpublic HashedCredentialsMatcher hashedCredentialsMatcher() {HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();// 散列算法:这里使用MD5算法;hashedCredentialsMatcher.setHashAlgorithmName("md5");// 散列的次数,比如散列两次,相当于 md5(md5(""));hashedCredentialsMatcher.setHashIterations(2);// storedCredentialsHexEncoded默认是true,此时用的是密码加密用的是Hex编码;false时用Base64编码hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);return hashedCredentialsMatcher;}

看一下我们自定义实现的 CustomRealm 类的 doGetAuthenticationInfo 方法的实现,如下:

@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {if(StringUtils.isEmpty(authenticationToken.getPrincipal())) {return null;}// 获取用户信息String userName = authenticationToken.getPrincipal().toString();User user = userService.selectByUserName(userName);// 用户是否存在if(user == null) {throw new UnknownAccountException();}// 是否激活if(user !=null && user.getStatus().equals("0")){throw new  DisabledAccountException();}// 是否锁定if(user!=null && user.getStatus().equals("3")){throw new  LockedAccountException();}// 若存在将此用户存放到登录认证info中,无需做密码比对shiro会为我们进行密码比对校验if(user !=null && user.getStatus().equals("1")){ByteSource credentialsSalt = ByteSource.Util.bytes(user.getUserName()+ "salt");/** 这里验证authenticationToken和simpleAuthenticationInfo的信息,构造方法支持三个或者四个参数,*  第一个参数传入userName或者是user对象都可以。*   第二个参数传入数据库中该用户的密码(记得是加密后的密码)* 第三个参数传入加密的盐值,若没有则可以不加*   第四个参数传入当前Relam的名字**/SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userName, user.getPassword().toString(),credentialsSalt, getName());return simpleAuthenticationInfo;}return null;}

shiro盐值加密(五)相关推荐

  1. java shiro盐值加密_java中spring-shiro实现密码的MD5盐值加密

    看了网上很多教程,都提到有配置spring shiro的密码加密方式,甚至给出了自定义的Class来实现.却很少有通过配置来解决的. 密码的盐值加密方式应该是非常通用的,也可以算是基础吧.按理说spr ...

  2. java shiro盐值加密_shiro盐值加密并验证

    在数据表中存的密码不应该是123456,而应该是123456加密之后的字符串,而且还要求这个加密算法是不可逆的,即由加密后的字符串不能反推回来原来的密码,如果能反推回来那这个加密是没有意义的.著名的加 ...

  3. Spring Boot 整合 shiro 之盐值加密认证详解(六)

    Spring Boot 整合 shiro 之盐值加密认证详解 概述 不加盐认证 加入密码认证核心代码 修改 CustomRealm 新增获取密文的方法 修改 doGetAuthenticationIn ...

  4. Shiro密码加密 盐值加密

    1.为什么要盐值加密 对于同一密码,同一加密算法会产生相同的hash值.这样,当用户进行身份验证时,对用户输入的明文密码应用相同的hash加密算法,得出一个hash值,然后使用该hash值和之前存储好 ...

  5. C#实现带盐值加密,适配JAVA Shiro加密

    C#实现带盐值加密,适配JAVA Shiro加密 前言 核心代码 Java代码 C#代码 注意 前言 工业领域上位机软件与管理系统通常使用不同编程语言实现,比如我们的上位机软件通常使用C#,而MES. ...

  6. Springboot + Shiro——MD5 盐值加密(配置)

    其实这里所说的盐,简单的说,就是一组安全随机数.它会在特定的时候,加入到密码中(一般来说是加密后的密码).从而使密码变得更有味道(从单一简单化到复杂化),更安全. 如何做到? 1). 在 doGetA ...

  7. shiro—MD5盐值加密

    本例为在idea下shiro集成springMVC.仅有一个认证加密方式(一个realm ) 为什么是MD5盐值加密呢?shiro用密码匹配,密码一样,就ok.如果两个用户的密码一样,则就会造成麻烦. ...

  8. Shiro(三) 身份认证源码分析与 MD5 盐值加密

    文章目录 1. 身份认证 2. 身份验证的基本流程 3. 身份验证实现 3.1 在 `login.jsp` 添加登录表单 3.2 添加表单提交的 Controller 3.3 完善 Realm 的身份 ...

  9. Shiro学习笔记-----小组开发前后端分离项目---登陆认证盐值加密

    当下我正在参与的学校前后端分离的实习项目,有了登录系统的需求,于是我在了解到Shiro是当下主流的安全框 架后,毅然决然开启了学习Shiro的旅程 首先来谈谈什么是Shiro,Apache Shiro ...

最新文章

  1. linux mysql5.1安装,1怎么安装?Linux环境下MySQL5?
  2. i.MX6 u-boot 怎么确定板级头文件
  3. Swaks - SMTP界的瑞士军刀
  4. python time 语句_python的time模块总结
  5. 数据结构——最小生成树之克鲁斯卡尔算法(Kruskal)
  6. MyBatis从入门到精通:update用法、delete用法
  7. java jpa 字段 关联_jpa查询关联表懒加载数据initialize proxy no session
  8. mysql 1114_ERROR 1114 (HY000): The table 'adv_date_tmp' is full(Mysql临时表应用)
  9. Java | PTA练习:伪随机数题解
  10. anovan matlab,matlab函数之anova用法
  11. 魔百盒CM211-2系列(ZG/CH/YS)海思MV300H/310芯片-刷机固件及教程
  12. 藏宝阁上架服务器信息错误,苦行虚空,难道在处罚中也能上架藏宝阁吗?
  13. 查询rssi指令_RSSI测量方法及网络设备、终端设备与流程
  14. 北京超级计算机中心,超级计算机“元”上线 北京超云中心正式服役
  15. Git强推本地代码到远程
  16. 修改android模拟器的路径
  17. Leader如何避免被下属忽悠?
  18. 可视化网盘系统的设计与实现过程记录
  19. tp5的通过php文件的打包与解包
  20. 链路聚合-VLAN原理和配置-VLAN间路由——总结

热门文章

  1. 宁波有好的学计算机编程的学校吗,学编程哪家学校好-宁波乐创世界
  2. MySQL数据库是非关系_关系型数据库和非关系型数据库的理解
  3. axure 8 表格合并_「WPS办公助手」如何用表格做数据分析?用这些方法整理,清晰又直观!...
  4. java计算机毕业设计进出口食品安全信息管理系统源码+mysql数据库+系统+lw文档+部署
  5. 测试岗人员转型已是必然选择:我的十年自动化测试经验分享
  6. 网友潜伏房产中介 曝光二手房买卖潜规则
  7. MySQL DELETE语句
  8. 【灼鼎咨询】中国制造业行业研究报告——我国制造业将不断转型升级,朝着世界制造强国的前列迈进
  9. go context详解
  10. 量化交易×AI音乐 | 数学之美 I.