一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

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

时间:2016-10-29 编辑:简简单单 来源:一聚教程网

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

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

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




value="select u.user_password,u.salt from auth_sys_user u where u.user_nick = ? and u.status=0" />
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)" />
value="SELECT p.permission_code FROM auth_role_permission p WHERE p.role_id = ? " />






解释一下:

①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;
}

热门栏目