使用char[]生成MD5哈希值

3

如何将使用以下方法获得的 char[] 密码转换:

char[] password = passwordInputField.getPassword();

转换为MD5哈希值?通常我会使用以下方法,但getBytes仅与字符串兼容:
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(password.getBytes());
String hashedPass = new BigInteger(1, md.digest()).toString(16);

不确定你的应用是什么,但通常不再使用MD5来进行安全目的。 - Neil Smithline
那么你会推荐使用什么? - Hrach Ghapantsyan
1
假设您想在登录时进行密码存储和验证,bcrypt 是今天的标准。请参阅此问题以获取Java实现。 - Neil Smithline
1个回答

1

注意:MD5散列算法不应用于密码存储,因为它的哈希很容易被破解。但是出于简单起见,我将使用它。

快速/简便/不安全的解决方法是将字符数组转换为字符串。然而,这种方法不安全,因为字符串是不可变的,并且无法从内存中清除。

String password = new String(passwordInputField.getPassword());

MessageDigest md = MessageDigest.getInstance("MD5");
md.update(password.getBytes());
String hashedPass = new BigInteger(1, md.digest()).toString(16);

一种更安全的解决方案:将char[]转换为byte[],然后清除数组中的数据。
private byte[] toBytes(char[] chars) {
    CharBuffer charBuffer = CharBuffer.wrap(chars);
    ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer);
    byte[] bytes = Arrays.copyOfRange(byteBuffer.array(),
            byteBuffer.position(), byteBuffer.limit());
    Arrays.fill(charBuffer.array(), '\u0000'); // clear sensitive data
    Arrays.fill(byteBuffer.array(), (byte) 0); // clear sensitive data
    return bytes;
}

char[] passChars = passwordInputField.getPassword();
byte[] passBytes = toBytes(passChars);

MessageDigest md = MessageDigest.getInstance("MD5");
md.update(passBytes);
String hashedPass = new BigInteger(1, md.digest()).toString(16);

Arrays.fill(passChars, '\u0000'); // clear sensitive data
Arrays.fill(passBytes, (byte) 0); // clear sensitive data

编辑:

更新了更安全的解决方案(感谢user2656928提供的想法)。

char[]转byte[]方法,由andreyne提供


1
快速简单,没错。但是为了安全考虑getPassword() 返回 char[]。在处理密码时应该牢记这一点。 - RealSkeptic
这将违反Swing返回密码作为char[]而不是String的安全原因 - 即字符串是不可变的,因此创建了一个字符串后,无法从内存中擦除它。使用char[],您可以在完成后覆盖数据(除非GC允许移动对象,并且不能指望它在移动时擦除原始数据)。如果您关心安全性,确实需要找到或编写一个char[]byte[]转换器,并在之后清除两个数组。 - Andy Lowry
2
@RealSkeptic 你说得没错,但如果那个MD5哈希直接传输或存储用于任何安全目的,那么整个系统比分配的字符串在内存中挂起更大的问题。 - Barend
没问题!谢谢,我相信我已经修复了错误。 - Connor
这种方式不安全,不能用于密码存储。 - Neil Smithline
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接