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

看了网上很多教程,都提到有配置spring shiro的密码加密方式,甚至给出了自定义的Class来实现。却很少有通过配置来解决的。

密码的盐值加密方式应该是非常通用的,也可以算是基础吧。按理说spring shiro不可能没有实现,让用户自己去实现吧。

通过读源码看各种关系,摸索出shiro的MD5盐值加密方式,分享一下 (shiro的maven仓库中的source从来都是个空文件,github上的源码又没有stable版本的代码,要调试很恼火),当然阅读源码可以直接到github上,https://github.com/apache/shiro
关于shiro的基础使用这里就不贴配置了,相关文章可以自己搜索。先贴出MD5盐值加密相关配置:

<bean id="jdbcRealm" class="org.apache.shiro.realm.jdbc.JdbcRealm">
<property name="dataSource" ref="tbDataSource" />
<property name="credentialsMatcher" ref="passwordMatcher" />
<property name="authenticationQuery"
value="select u.user_password,u.salt from auth_sys_user u where u.user_nick = ? and u.status=0" />
<property name="userRolesQuery"
value="select r.role_id from auth_user_role r where r.user_id = (select u.user_id from auth_sys_user u where u.user_nick = ? and u.status=0)" />
<property name="permissionsQuery"
value="SELECT p.permission_code FROM auth_role_permission p WHERE p.role_id = ? " />
<property name="permissionsLookupEnabled" value="true" />
<property name="saltStyle" value="COLUMN" />
</bean>
<bean id="passwordMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="MD5"/>
<property name="hashIterations" value="2"/>
</bean>

解释一下:

①credentialsMatcher属性是认证匹配的方式,这个属性使用org.apache.shiro.authc.credential.HashedCredentialsMatcher的方式。HashedCredentialsMatcher是Hash认证匹配的方式,阅读源码发现这个类有4个属性hashAlgorithm 、hashIterations 、hashSalted 、storedCredentialsHexEncoded。
其中hashAlgorithm表示hash算法名称,String类型,常见的有MD2、MD5、SHA1、SHA256、SHA384、SHA512等。

hashIterations表示hash迭代的次数,int类型,也就是加密次数,默认是1次。
hashSalted表示hash是否加盐,boolean类型,这个属性已经被标为过期,不建议使用,实际上这个属性在Realm的配置中已决定。
storedCredentialsHexEncoded表示是否存储散列后的密码为16进制(HEX),boolean类型,默认为true,否则将会以base64编码。
②saltStyle配置为COLUMN表示salt从数据库字段中获取,这时候相应的authenticationQuery查询结果,第一个字段为password,第二个字段就是salt。除此之外,saltStyle还有几个可选值,分别为NO_SALT、CRYPT、EXTERNAL。其中NO_SALT表示没有盐值;CRYPT表示salt值存在unix的加密文件中;EXTERNAL表示salt并不存在数据库中,而是通过调用JdbcRealm.getSaltForUser(username)方法得到,这个方法其实就是返回username。
当然,实现了密码的MD5盐值加密之后,在插入用户、修改用户密码的时候,就需要用同样的算法对密码进行处理,包括生成salt入库等。
对于在程序中生成加密后的密码,可以参考以下代码:

Md5Hash hash = new Md5Hash(password,salt,2);
return hash.toString();

当然,你也可以用SimpleHash,通过第一个参数指定加密算法名称(与credentialsMatcher 中配置的相同):
SimpleHash hash = new SimpleHash("MD5", password,salt,2);
return hash.toString();
对于生成随机的salt,可以使用shiro自带的SecureRandomNumberGenerator生成,如下:
private String generateSalt(){
        SecureRandomNumberGenerator secureRandom = new SecureRandomNumberGenerator();
        String hex = secureRandom.nextBytes(3).toHex(); //一个Byte占两个字节,此处生成的3字节,字符串长度为6
        return hex;
}

时间: 2024-09-17 22:22:53

java中spring-shiro实现密码的MD5盐值加密的相关文章

Java中Spring获取bean方法小结_java

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架,如何在程序中获取Spring配置的bean呢? Bean工厂(com.springframework.beans.factory.BeanFactory)是Spring框架最核心的接口,它提供了高级IoC的配置机制.BeanFactory使管理不同类型的Java对象成为可能,应用上下文(com.springframework.context.ApplicationContext)建立在BeanFactory基础之上,提供

java中由random()实施生随机数生成器如何抵挡加密攻击

问题描述 java中由random()实施生随机数生成器如何抵挡加密攻击 解决方案

java数据类型-java中只要是基本数据类型的变量初始值问题

问题描述 java中只要是基本数据类型的变量初始值问题 java中只要是基本数据类型的变量 int a;和int a =0是一样的 只要是引用数据类型变量 String a = null; String a; 是一样的 以上说法正确吗 解决方案 基本数据类型对.引用的值不初始化是没有默认值的,引用的数据类型变量不初始化是不能用的.必须初始化了别的地方才能用.因为没有引用的内存地址. 解决方案二: 你分别打印String a = null; String a; 看看. 解决方案三: java中基本

java-C#中将double值变成二进制然后写入文件,Java中载入该文件读取此二进制double值时不正确

问题描述 C#中将double值变成二进制然后写入文件,Java中载入该文件读取此二进制double值时不正确 目前已定位到是因为C#中的byte范围是0到255,而java中byte值为-128到127导致的错误. 尝试过使用C#的sbyte来解决: bw1 = new BinaryWriter(new FileStream("C:UsersDELLDesktopSpatialIndexctest1.bin", FileMode.Create)); bw2 = new BinaryW

java中一个void修饰的方法无返回值,那么有是不是返回一个空对象,有空对象这种说法吗

问题描述 java中一个void修饰的方法无返回值,那么有是不是返回一个空对象,有空对象这种说法吗 java中一个void修饰的方法无返回值,那么有是不是返回一个空对象,有空对象这种说法吗 解决方案 加入你有一个对象 Object 里面有个方法:public void method1(); 那你调用这个方法的时候就是 object.method1(); 那么这里就表示 没有返回值. 所以我里面的void就是 :没有返回值,这个方法不能做他用! 对比 有一个object 里面有一个方法: publ

什么是md5盐值

简单说就是为了使相同的密码拥有不同的hash值的一种手段 就是盐化 MD5自身是不可逆的 但是目前网路上有很多数据库支持反查询 如果用户密码数据库不小心被泄露 黑客就可以通过反查询方式获得用户密码 或者对于数据库中出现频率较高的hash码(即很多人使用的)进行暴力破解(因为它通常都是弱口令) 盐值就是在密码hash过程中添加的额外的随机值 比如我的id是癫ω倒④ゞ 密码是123456 存在数据库中的时候就可以对字符串"123456/癫ω倒④ゞ "进行hash,而验证密码的时候也以字符串

java中spring security的remember me异常解决办法

 想想也不可能,网络中不会时不时出现cookie theft攻击吧.看了官方文档,也没给出解释,后来在oschina看到一篇分析的文章,才明白其中的缘由,文章<是谁动了我的cookie?Spring Security自动登录功能开发经历总结>. 从这篇文章的分析结合spring secutiy的源码来看,在每次持久化登录校验token完毕之后,会更新token的值并写入cookie.而token的校验是通过加密处理写入cookie中的字符串与持久化存储的token做对比看是否一致来判断登录信息

Java中Spring发送邮件实现与用中文发件人昵称

百度找了半天发现问题关键在于使用固定的格式来填充From属性,如下:  代码如下 复制代码 // 设置收件人,寄件人 String nick = javax.mail.internet.MimeUtility.encodeText("您的昵称"); messageHelper.setFrom(new InternetAddress(nick + " <service@caomeishuo.com>")); messageHelper.setTo(toMa

JAVA中 Spring定时器的两种实现方式_java

目前有两种流行Spring定时器配置:Java的Timer类和OpenSymphony的Quartz. 1.Java Timer定时 首先继承java.util.TimerTask类实现run方法 import java.util.TimerTask; public class EmailReportTask extends TimerTask{ @Override public void run() { ... } } 在Spring定义 ... 配置Spring定时器 <bean id=&quo