我正在使用Shiro和Spring MVC登录用户。我在applicationContext.xml中配置了Shiro(没有INI文件)。
这是领域配置:
<bean id="myRealm" class="org.apache.shiro.realm.jdbc.JdbcRealm">
<property name="dataSource" ref="dataSource"/>
<property name="authenticationQuery" value="select password from usuarios where email = ?"/>
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="storedCredentialsHexEncoded" value="false"/>
<property name="hashIterations" value="1024" />
</bean>
</property>
</bean>
这是我的代码在用户注册时生成salt和hash:
RandomNumberGenerator rng = new SecureRandomNumberGenerator();
Object salt = rng.nextBytes();
String hashedPasswordBase64 = new Sha256Hash(password, salt, 1024).toBase64();
u.setPassword(hashedPasswordBase64);
u.setSalt(salt.toString());
usuarioDao.saveUsuario(u);
这里saveUsuario(u)调用DAO将用户持久化在MySQL中。我猜salt.toString()是错误的。
用户表是:
CREATE TABLE usuarios (
id INTEGER AUTO_INCREMENT,
nombre VARCHAR(50),
...
password VARCHAR(50),
salt VARCHAR(50),
...
PRIMARY KEY (id)
);
问题是: - 哪个类型应该是DB中的哈希字段?散列由rng.nextBytes创建,类型为Object。 - 如何将字段或查询声明为HashedCredentialsMatcher,以便它可以正确进行身份验证?
答案 0 :(得分:1)
首先,请阅读Thomas Pornin's canonical answer to How to securely hash passwords。
然后,请注意Java 8 does have PBKDF2-HMAC-SHA-512 available now为PBKDF2WithHmacSHA512 - 请改用它。特别是SHA-512具有64位操作,可以降低基于GPU的攻击者的优势。使用比1024更多的迭代 - 看看你的系统在负载下可以轻松处理!
使用那些,或BCrypt或SCrypt。使用至少12字节的加密随机盐。
不要求PBKDF2-HMAC-SHA-512中超过64个(二进制)字节,超过PBKDF2-HMAC-SHA-256中的32个(二进制)字节,要么超过20个(二进制)字节PBKDF2-HMAC-SHA-1,或者你积极地为攻击者提供优势。
您绝对可以将数据库中的散列和salt存储在BINARY()字段中,也可以将它们转换为Base64或十六进制;这完全取决于你。 BINARY()是最小的,不需要进入或退出转换。
答案 1 :(得分:0)
我在这个主题中找到了答案:how to get/set the salt for a JdbcRealm
我将JdbcRealm扩展为:
public class JdbcSaltRealm extends JdbcRealm {
public JdbcSaltRealm() {
setSaltStyle(SaltStyle.COLUMN);
}
}
然后我将applicationContext.xml中的myRealm更改为:
<bean id="myRealm" class="ar.com.yojunto.webapp.security.JdbcSaltRealm">
<property name="dataSource" ref="dataSource"/>
<property name="authenticationQuery" value="select password, salt from usuarios where email = ?"/>
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="SHA-256" />
<property name="hashIterations" value="1024" />
</bean>
</property>
</bean>
最后将数据库更改为:
password VARCHAR(64),
salt VARCHAR(50),
我不知道这种算法的盐有多强,但效果很好。