如何升级密码存储方案(更改哈希算法)

发布于 2024-08-07 22:12:10 字数 517 浏览 6 评论 0原文

我被要求对 Intranet 站点进行一些更改/更新;正如他们所说,使其成为“面向未来”。

我们发现密码是使用 MD5 算法进行哈希处理的。 (该系统自 2001 年以来就已经存在,所以当时已经足够了)。
我们现在想要将哈希算法升级为更强的算法(BCrypt-hash 或 SHA-256)。

我们显然不知道明文密码,并且为用户库创建新密码不是一个选项*)

所以,我的问题是:

在无法访问明文密码的情况下更改哈希算法的可接受方法是什么?
最好的解决方案是完全“在幕后”的解决方案。

<子> *)我们尝试过;为了说服他们,我们使用了“密码年龄”的论点,试图用咖啡贿赂他们,试图用蛋糕贿赂他们等等。但这不是一个选择。

更新
我希望有某种自动解决方案来解决问题,但显然除了“等待用户登录,然后转换”之外没有其他选择。

好吧,至少现在我现在没有其他的解决办法了。

I've been asked to implement some changes/updates to an intranet-site; make it 'future proof' as they call it.

We found that the passwords are hashed using the MD5 algorithm. (the system has been around since 2001 so it was adequate at time).
We would now like to upgrade the hashing-algorithm to a stronger one (BCrypt-hash or SHA-256).

We obviously do not know the plaintext-passwords and creating a new password for the userbase is not an option*).

So, my question is:

What is the accepted way to change hashing-algorithm without having access to the plaintext passwords?
The best solution would be a solution that is entirely 'behind the scenes'.


*) we tried; tried to convince them, we used the argument of 'password age', tried to bribe them with coffee, tried to bribe them with cake, etc. etc. But it is not an option.

Update
I was hoping for some sort of automagic solution for solving the problem, but apparently there are no other options than just 'wait for the user to log in, then convert'.

Well, at least now I now there is no other solution available.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

怕倦 2024-08-14 22:12:10

首先,在数据库中添加一个字段来识别密码是使用MD5还是新算法。

对于仍然使用 MD5 的所有密码:

-- 在登录过程中,验证用户输入的密码:将用户提交的密码临时存储在内存中(这里没有安全问题,因为它已经在内存中的某处)并执行通常的 MD5 哈希&与存储的哈希值进行比较;

-- 如果给出了正确的密码(与现有哈希匹配),则通过新算法运行临时存储的密码,存储该值,更新新字段以标识该密码已更新为新算法。

(当然,您只需对任何新用户/新密码使用新算法。)

First, add a field to the DB to identify whether or not the password is using MD5 or the new algorithm.

For all passwords still using MD5:

-- In the login process, where you verify a user's entered password: temporarily store the user's submitted password in memory (no security issue here, as it is already in memory somewhere) and do the usual MD5 hash & compare with the stored hash;

-- If the correct password was given (matches the existing hash), run the temporarily stored password through the new algorithm, store that value, update the new field to identify that this password has been updated to the new algorithm.

(Of course you would just use the new algorithm for any new users/new passwords.)

谎言 2024-08-14 22:12:10

我不完全确定这个选项,因为我不是密码学专家。如果我在某些地方错了,请纠正我!

我认为 Dave P. 显然是最好的选择。

... 但。有一个自动解决方案 - 对旧的哈希值本身进行哈希处理。也就是说,获取当前的哈希值,并使用更强的算法再次对它们进行哈希处理。请注意,据我了解,这里的哈希长度不会增加任何安全性,只会增加新算法的加密复杂性。

当然,问题是检查密码必须通过两个哈希值。您还必须对每个新密码执行相同的操作。嗯,这非常愚蠢。除非您想使用像 Dave P. 解释的类似方案,最终使用新的哈希算法返回到单哈希密码……在这种情况下,为什么还要为此烦恼呢? (当然,您可能会在公司诉讼的演示中以一种华丽的“提高所有密码的安全性,立即应用!”的方式使用它,并且表情相对严肃......)

尽管如此,它仍然是一个可以立即应用的选项所有当前密码,无需任何逐步迁移阶段。

但是天哪,天哪,以后有人看到这段代码会开怀大笑吗! :)

I'm not entirely sure about this option, since I'm not an expert on cryptography. Please correct me if I'm wrong at some point here!

I think Dave P. has clearly the best option.

... but. There is an automagic solution - hash the older hashes themselves. That is, take the current hashes, and hash them again with a stronger algorithm. Notice that as far as I understand, you don't get any added security from hash length here, only the added cryptographical complexity of the new algorithm.

The problem is, of course, that checking a password would then have to go through both hashes. And you'd have to do the same for evey new password as well. Which is, well, pretty much silly. Unless you want to use a similar scheme like Dave P. explained to eventually graduate back to single-hashed passwords with the new hashing algorithm... in which case, why even bother with this? (Granted, you might use it in a flashy "Improved security for all passwords, applied immediately!"-way at a presentation to corporate suits, with a relatively straight face...)

Still, it's an option that can be applied immediately to all current passwords, without any gradual migration phase.

But boy, oh boy, is someone going to have a good laugh looking at that code later on! :)

巴黎盛开的樱花 2024-08-14 22:12:10

将passwordChange日期时间字段添加到数据库中。

X 天之前设置的所有密码,使用 MD5 检查

X 天之后设置的所有密码,使用 BCrypt 或其他方式检查。

Add passwordChange datetime field to the database.

All password set before day X, check using MD5

All passwords set after day X, check using BCrypt or whatever.

梦年海沫深 2024-08-14 22:12:10

您可以将用于创建该哈希的算法存储在哈希字段本身(例如“MD5:d41d8cd98f00b204e9800998ecf8427e”)或另一列中。然后,您必须修改登录过程,以便在检查密码时使用正确的算法。当然,任何新密码都将使用新算法进行哈希处理。希望密码最终会过期,并且随着时间的推移,所有 MD5 哈希值都将被逐步淘汰。

You could store, either in the hash field itself (e.g. "MD5:d41d8cd98f00b204e9800998ecf8427e") or in another column, which algorithm was used to create that hash. Then you'd have to modify the login process to use the correct algorithm when checking the password. Naturally, any new passwords will be hashed using the new algorithm. Hopefully, passwords eventually expire, and over time all of the MD5 hashes will be phased out.

多彩岁月 2024-08-14 22:12:10

由于您不知道明文密码,也许您应该创建一个指示加密版本的字段(例如PasswordVersion位默认0

下次用户尝试登录时,使用当前算法版本检查散列密码,就像你今天做的那样。如果匹配,则再次对其进行哈希处理并更新 PasswordVersion 字段。

希望您不需要比 bit 大的 PasswordVersion 列。 =)

Since you don't know plaintext password, maybe you should to create a field which indicates encription version (like PasswordVersion bit default 0)

Next time user tries to log in, check hashed password using current algorithm version, just like you do today. If it matches, hash it again and update PasswordVersion field.

Hopefully you'll not need a PasswordVersion column bigger than bit. =)

花落人断肠 2024-08-14 22:12:10

您应该更改密码数据库以存储 3 项:

  1. 算法标识符。
  2. 服务器在首次计算和存储密码哈希时选择的随机盐字符串。
  3. 使用指定算法连接盐+密码的哈希值。

当然,这些可以用分隔符一起存储在一个文本字段中:

“SHA256:这是盐:这是哈希值”

现在将现有条目转换为具有空盐和旧算法的值

“MD5::这是旧的 md5 哈希值,不加盐”

现在您有足够的信息来验证所有现有的密码条目,但您也可以验证新条目(因为您知道使用了哪个哈希函数) 。您可以在现有用户下次登录时将旧条目转换为新算法,因为在此过程中您将获得他们的密码:

  1. 如果您的数据库表明他们正在使用不带盐的旧算法,请首先通过旧方式验证密码检查密码的 MD5 哈希值是否匹配。如果没有,则拒绝登录。
  2. 如果密码已验证,则让服务器选择一个随机盐字符串,计算盐+密码的 SHA256 哈希值,并用指定新算法、盐和哈希值的新条目替换密码表条目。
  3. 当用户再次登录时,您会看到他们正在使用新算法,因此计算盐+密码的哈希值并检查它是否与存储的哈希值匹配。

最终,在该系统运行一段合适的时间后,您可以禁用尚未转换的帐户(如果需要)。

添加每个条目独有的随机盐字符串使得该方案更能抵抗使用彩虹表的字典攻击。

You should change your password database to store 3 items:

  1. An algorithm identifier.
  2. A random salt string chosen by the server when it first computes and stores the password hash.
  3. The hash of the concatenation of salt+password using the specified algorithm.

Of course these could just be stored together in one text field with a delimiter:

"SHA256:this-is-salt:this-is-hash-value"

Now convert you existing entries to a value with empty salt and the old algorithm

"MD5::this-is-the-old-md5-hash-without-salt"

Now you have enough information to verify all you existing password entries, but you can also verify new entries (since you know which hash function was used). You can convert the old entries to the new algorithm the next time the existing users login since you will have their password available during this process:

  1. If your database indicates they are using the old algorithm with no salt, first verify the password the old way by checking that the MD5 hash of the password matches. If not, reject the login.
  2. If the password was verified, have the server choose a random salt string, compute the SHA256 hash of the salt+password, and replace the password table entry with a new one specifiy the new algorithm, salt and hash.
  3. When the user logs in again, you'll see they are using the new algorithm, so compute the hash of the salt+password and check that it matches the stored hash.

Eventually, after this system has been running for a suitable time, you can disable accounts that haven't been converted (if desired).

The addition of a random salt string unique to each entry makes this scheme much more resistent to dictionary attacks using rainbow tables.

夏至、离别 2024-08-14 22:12:10

最佳答案来自真正的密码学专家
https://paragonie.com/ blog/2016/02/how-safely-store-password-in-2016#legacy-hashes

这篇文章还有助于解释您应该使用哪种哈希。即使它写着 2016,它仍然是最新的。如果有疑问,请使用 bcrypt。

在您的用户帐户表中添加一列,称为legacy_password(或同等内容)。这只是一个布尔值

,计算现有密码哈希值的新的更强的哈希值并将它们存储在数据库中。

修改您的身份验证代码以处理旧标志。

当用户尝试登录时,首先检查是否设置了legacy_password标志。如果是,请首先使用旧密码哈希算法对其密码进行预哈希,然后使用此预哈希值代替其密码。然后(md5),重新计算新的哈希值并将新的哈希值存储在数据库中,在此过程中禁用legacy_password标志。

The best answer is from an actual cryptography expert
https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016#legacy-hashes

This post also helps explain which hashing you should use. It's still current even if it says 2016. If in doubt use bcrypt.

Add a column to your user accounts table, called legacy_password (or equivalent). This is just a Boolean

Calculate the new stronger hash of the existing password hashes and store them in the database.

Modify your authentication code to handle the legacy flag.

When a user attempts to login, first check if the legacy_password flag is set. If it is, first pre-hash their password with your old password hashing algorithm, then use this prehashed value in place of their password. Afterwards (md5), recalculate the new hash and store the new hash in the database, disabling the legacy_password flag in the process.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文