我正在尝试使用 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 安装的模块目录中,但它一定是一个较旧的示例,因为我没有看到它。
最佳答案
您的问题是使用BigInteger
来创建十六进制编码; BigInteger
可以在字节数组中使用大端编码创建。但是,如果字节数组以一个或多个 00
值字节开头,则这些字节可能会被删除。使用 Guava、Apache Codec 或 Bouncy CaSTLe 来创建十六进制字符串。
也就是说,您应该使用基于密码的 key 派生函数 (PBKDF),例如 PBKDF2(存在于标准 Java API 中)、bcrypt 或 scrypt 来存储密码“哈希值”。这些输出字节也是如此,因此如果您需要文本,您仍然需要对其进行编码。
另请注意,String.getBytes()
使用平台编码,您只能使用它来与标准进行通信。相反,您应该向 String.getBytes()
方法提供字符编码,例如使用String.getBytes(StandardCharsets.UTF_8)
。
关于java - 使用哈希密码时凭据不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23726117/