使用散列密码时,凭据不正确

时间:2014-05-18 19:41:37

标签: java encryption jboss sha256

我正在尝试使用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属性,并将密码存储在clear中时,身份验证工作正常。任何人都可以看到我的加密方法有任何问题吗?

<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安装的模块目录中,但它一定是一个较旧的例子,因为我没有看到它。

1 个答案:

答案 0 :(得分:1)

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

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

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