【问题标题】:Can't get to have SHA-256 hash working with my spring security无法让 SHA-256 哈希与我的 Spring Security 一起使用
【发布时间】:2014-05-20 10:08:24
【问题描述】:

我正在使用 Spring Roo 框架,它使用 Spring Security 作为安全框架。我是这样配置的:

<authentication-manager alias="authenticationManager">
    <!-- SHA-256 values can be produced using 'echo -n your_desired_password | sha256sum' (using normal *nix environments) -->
    <authentication-provider>
        <password-encoder hash="sha-256">
            <!-- <salt-source user-property="login"/> -->
        </password-encoder>
        <jdbc-user-service data-source-ref="dataSource"
            users-by-username-query="
            SELECT login, password, enabled
            FROM user WHERE login = ?"

            authorities-by-username-query="
            SELECT u.login, r.authority
            FROM user u, rol r, 
            usuer_role ur
            WHERE u.login = ur.usuarer
            AND r.roleId = ur.role
            AND u.login = ?"        
        />
        <user-service>
            <user name="admin" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" authorities="ROLE_ADMIN" />
            <user name="user" password="04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c85b9df8fb" authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>

为了使密码匹配,我编辑了UserController create 方法,以便应用 SHA-256 哈希存储密码,与安全配置文件 applicationContext-security.xml 中配置的相同。

这就是我的做法:

public String create(@Valid User user, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) throws NoSuchAlgorithmException, UnsupportedEncodingException {
    if (bindingResult.hasErrors()) {
        populateEditForm(uiModel, usuario);
        return "security/users/create";
    }
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.update(user.getPassword().getBytes("UTF-8"));
    byte[] digest = md.digest();
    usuario.setPassword( new String(digest, "UTF-8"));
    uiModel.asMap().clear();
    user.persist();
    return "redirect:/security/users/" + encodeUrlPathSegment(usuario.getId().toString(), httpServletRequest);
}

我尝试将密码设置为admin,与配置文件为默认用户提供的密码相同:admin,密码:admin,以检查我的create方法生成的密码是否匹配。

但是,配置文件中的哈希密码是 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918,但是当我通过控制台检查我的 mysql 数据库时,存储在数据库中的密码是一组奇怪的字符,或者当显示在页面中时是 ivAMgsKo*H

有什么帮助吗?

【问题讨论】:

  • SHA-256 的输出不是 UTF-8 编码的文本。似乎您想使用base64编码将byte[]摘要转换为字符串而不是new String(digest, "UTF-8")
  • 我做了这个 byte[] digest = Base64.encodeBase64(md.digest()); user.setClave(new String(digest)); 但现在密码是 jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg= 而不是 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
  • 糟糕,您需要使用hex encoding,而不是您最初尝试使用 UTF-8 或我最初建议使用 Base64。
  • 您不应该使用 SHA 作为密码哈希 - 这是一个非常糟糕的选择。例如,只需尝试将哈希值输入谷歌,您就会立即find the password。使用bcrypt instead

标签: java spring spring-mvc spring-security sha


【解决方案1】:

感谢@Oleg Estekhin 的评论,我终于想出了这个解决方案:

public String sha256(String original) throws NoSuchAlgorithmException {
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.update(original.getBytes());
    byte[] digest = md.digest();
    return new String(Hex.encodeHexString(digest));
}

【讨论】:

  • 你可以使用import javax.xml.bind.DatatypeConverter;中的DatatypeConverter.printHexBinary(digest)代替Hex.encodeHexString
【解决方案2】:

但是,配置文件中的哈希密码是 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 但是当我通过控制台或 ivAMgsKo*H 在页面中显示时。

8c6976e5b541041... 

看起来像 Base64 编码的数据。

虽然

 ivAMgsKo*H

和你的代码

new String(digest, "UTF-8")

告诉我,您的摘要未编码,而是存储为 UTF-8 字符串。

哈希值可以包含不可打印的字节值,因此通常对值进行编码。例如使用 Base64。

【讨论】:

  • 那我应该怎么做呢?
猜你喜欢
  • 2014-08-19
  • 2015-10-19
  • 2023-03-18
  • 2013-01-09
  • 1970-01-01
  • 2012-07-16
  • 2021-10-29
  • 2021-11-25
  • 1970-01-01
相关资源
最近更新 更多