如果我只使用一次,我应该散列用户输入的密码吗?

Should I hash a user-entered password if I only use it once?

我正在编写一个 Java 程序,它只登录一个网站并做一些无关紧要的事情。我预计我以外的人会使用它。所以,我有一个对话框(在终端中)要求用户输入密码,然后使用该密码登录。之后,我不需要密码。

我使用 java.io.console 中的 readPassword() 方法,它将密码存储在 char[] 中。完成密码后,我遍历数组并将所有值设置为 0。

够了吗?我应该散列密码吗?老实说,我不太明白散列密码的意义。我的 char 数组可能被破坏的唯一方法是攻击者可以访问我的程序内存。但是,如果攻击者可以访问我的程序内存,那么即使我进行哈希处理,当用户 enters/when 我将其转换为 String 以使用它登录时,他们是否也无法看到密码?

感谢您的帮助!作为参考,我正在使用 HTMLUnit 库进行登录。不确定这是否相关。

不,如果您只是使用并丢弃密码,则不应散列密码。

散列用于长期密码存储,通常在过程的任何描述中都明确指出:

这里是Wikipedia

Storing all user passwords as cleartext can result in a massive security breach if the password file is compromised. One way to reduce this danger is to only store the hash digest of each password.

这里是NIST 800-63B

[The Key Derivation Functions' (i.e. password hasher's)] purpose is to make each password guessing trial by an attacker who has obtained a password hash file expensive and therefore the cost of a guessing attack high or prohibitive.

这里是Wired

When hackers compromise a company to access its collection of users’ passwords, what they find and steal isn’t stored in a form that’s readable by humans—at least if the company has even a pretense of security. Instead, the cache of passwords is often converted into a collection of cryptographic hashes [..] to prevent them from being misused.

其次,密码散列仅在您验证 密码时适用,即当有人登录您的program/service 时。如果您输入的密码用于通过不同的服务进行身份验证,则它不适用。像密码管理器这样的程序不会对存储的密码进行哈希处理,即使它会长期存储它们,因为它是各种远程服务而不是密码管理器来验证密码(但是,它 会加密 密码)。

对用于在某处登录然后立即丢弃的密码进行散列处理没有任何意义。

但是,请注意,如果可能的话,您应该而不是char[]转换为字符串。如果你把它变成一个字符串,你就失去了对字符数据生命周期的控制。 When/if String 被收集,不能保证数据在内存中被覆盖,它可能比整个 JVM 更持久。 Heartbleed、Spectre 和 RowHammer 等各种备受瞩目的攻击可以利用在内存中保留的时间超过必要时间的密码。