【问题标题】:Credentials are incorrect when using hashed passwords使用散列密码时凭据不正确
【发布时间】:2014-05-19 15:46:56
【问题描述】:

我正在尝试使用 sha 256 加密存储用户密码。我有以下加密密码的方法:

    public static String hashPassword(String password) {
       MessageDigest mdEnc = null;
       try {
         mdEnc = MessageDigest.getInstance("SHA-256");
       }  catch (NoSuchAlgorithmException e) {
        return null;
       }
       mdEnc.update(password.getBytes(), 0, password.length());

       return new BigInteger(1, mdEnc.digest()).toString(16);
}

我在我的安全域中声明了以下内容,但每次我尝试登录时,它都说凭据不正确。当我不使用加密并删除 hashAlgorithm 和 hashEncoding 属性并将密码明文存储时,身份验证工作正常。有人能看出我的加密方法有什么问题吗?

<module-option name="hashAlgorithm" value="SHA-256"/>
<module-option name="hashEncoding" value="base64"/>

我试图遵循一个具有简单加密方法的示例:

import org.jboss.security.auth.spi.Util;

public class PasswordGenerator {
   public static void main(String[] args) {
     for (String arg : args) {
        System.out.println(new PasswordGenerator().generate(arg));
     }
    }
   private String generate(String password) {
     return Util.createPasswordHash("SHA-256", "BASE64", null, null,password);
   }
}

问题是它说包含 Util 类的 jar 在 JBoss 安装的模块目录中,但它一定是一个较旧的示例,因为我没有看到它。

【问题讨论】:

    标签: java encryption jboss sha256


    【解决方案1】:

    您的问题是使用BigInteger 创建十六进制编码; BigInteger 可以使用字节数组中的大端编码创建。但是,如果字节数组以一个或多个 00 值字节开始,则这些字节可能会被剥离。改用 Guava、Apache Codec 或 Bouncy Castle 创建十六进制字符串。

    也就是说,您应该使用基于密码的密钥派生函数 (PBKDF),例如 PBKDF2(存在于标准 Java API 中)、bcrypt 或 scrypt 来存储密码“哈希”。这些输出字节也是如此,所以如果您需要文本,您仍然需要对其进行编码。

    还要注意String.getBytes() 使用平台编码,您应该只使用它与标准进行通信。相反,您应该为 String.getBytes() 方法提供字符编码,例如使用String.getBytes(StandardCharsets.UTF_8)

    【讨论】:

    • 或者使用DatatypeConverter.printHexBinary(),这是从Java 6开始的标准库。
    • @Duncan 当然正确,但我既不喜欢 API,也不喜欢它包含在(可选)javax.xml.bind 包中的事实。
    猜你喜欢
    • 1970-01-01
    • 2021-02-19
    • 2017-04-10
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 2015-04-19
    • 2019-12-12
    相关资源
    最近更新 更多