如何在mysql数据库中存储salt以进行安全密码加密?

时间:2016-02-07 23:13:35

标签: spring-mvc hash shiro salt password-encryption

我正在使用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,以便它可以正确进行身份验证?

2 个答案:

答案 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),

我不知道这种算法的盐有多强,但效果很好。