相比起单纯对密码进行Hash加密,随机盐(salt)的使用可以进一步提高安全系数。本文介绍了如何在Grails的Shiro插件中使用随机盐。
所谓随机盐,是一串随机字符串,如果salt不一样则加密出来的结果也是不一样的。
首先为User添加字段passwordSalt用于保存随机盐:
class ShiroUser {
String username
String passwordHash
String passwordSalt
......
}
创建用户的时候,随机生成盐,并用随机盐生成密码的哈希值:
import org.apache.shiro.crypto.hash.Sha256Hash
import org.apache.shiro.crypto.SecureRandomNumberGenerator
String salt = new SecureRandomNumberGenerator().nextBytes().toHex() //随机生成盐
ShiroUser user = new ShiroUser(username:"admin" //密码值
, passwordHash:new Sha256Hash("admin", salt)
, passwordSalt:salt)
user.save()
接下来就需要修改认证代码了,在缺省生成的realms\ShiroDbRealm.groovy文件中:
def account = new SimpleAccount(username, user.passwordHash,"ShiroDbRealm") //将上述代码修改为如下代码 def bytesource=new SimpleByteSource(user.passwordSalt) def account = new SimpleAccount(username, user.passwordHash,bytesource,"ShiroDbRealm")
好了,OK!就是这么简单!快给你的应用也加点盐吧!

关于随机盐使用心得
String salt = new SecureRandomNumberGenerator().nextBytes().toHex() //随机生成盐
String hash = new Sha512Hash("admin", salt)
def admin =
new User(username: "admin", passwordHash: hash, passwordSalt: salt).save()
在User中,限制字段长度
passwordHash(nullable: false, blank: false, maxSize:128)
注:SHA256是64位,SHA512是128位,可根据实际情况调整
passwordSalt(nullable: false, blank: false, maxSize:256)
二、使用心得
1、环境:Grails 1.3.7 + Groovy 1.7.8 + MySQL
2、失败原因
2.1、不知道是不是数据库的原因,因为salt的长度是256,在MYSQL中是BLOB型的字段,如果不指定的话,则失败。
2.2、写成这样也不行,不知道为什么
def admin =
new User(
username: "admin"
, passwordHash: new Sha512Hash("admin", salt)
, passwordSalt: salt
).save()
有兴趣的可以试试,找出原因,谢谢!
我这里的环境也是Grails 1.3.7+Groovy 1.7.8
我这里的环境也是Grails 1.3.7+Groovy 1.7.8.
是要在指定salt的长度,因为salt的长度是256,指定maxSize:256,在mysql中会使用LongText的类型。
我将salt字段改成blob,使用Sha512Hash也是好的。