我有一个数据数据库,其中密码列使用sha1值。我打算将我的加密方法更新为Bcrypt或sha256。想得到一个脚本,它将所有sha1密码更新为sha256或Bcrypt值。非常感谢
示例:如果我的密码是hari
sha1
给出
46ebaaa2b80c7a3459b80353e085aaeed5aff2ff
sha256
给出
f7b3781c5eafc2779a96bae2e4875a83ecce46f198e9f81916521d9d218c7da7
我要将所有sha1更改为sha256
由于哈希操作不可逆,因此无法更改哈希值。也就是说,您可以将纯文本转换为哈希值,但不能反过来。 因此,更好的想法是为sha256密码创建一个不同的表。并在下次登录时继续将用户移植到其他表。 即,用户下次登录时,从现有表中检查密码是否正确。如果发现用户是正确的,则使用sha256重新扫描密码并将其保存到另一个(新)表。这样最终,当用户登录时,您可以将它们移植到更安全的sha256哈希密码。 移植用户后,您可以从旧表中删除它们的条目(在任何批处理脚本的当前/之后)。
现在来了如何处理登录。这将是一个两步过程,直到所有用户都被移植。 1.首先检查较新的表格。如果发现没问题,请继续。 2.另外检查旧桌子。
在其他答案或评论中已经说了很多。
基本上,您不能简单地从散列值移动到与初始值对应的另一个散列值。哈希函数是单向函数。
但不要害怕,有希望!这是一种方法,可以让您:
这个很重要。请仔细阅读。
对于密码存储,不应使用任何(加密)散列函数,如SHA1,SHA2甚至SHA3(Keccak)。主要原因是他们很快。太快。这不是你应该通过密码散列茁壮成长的东西。 More information。
此外,他们不处理腌制,这意味着您需要手动执行此操作,这意味着您有更高的机会搞砸它。
对于密码存储,您需要为此明确目的而使用密码散列函数。你有几个众所周知的功能:PBKDF2,BCrypt,SCrypt或Argon2。
这些函数可以处理盐并且速度很慢(性能可通过参数调整)。
既然你使用PHP,这对你来说更简单。 password_hash()
功能为您提供了一个漂亮且工作正常的蝙蝠BCrypt。用它!
如果您使用的是PHP 7.2+,它甚至支持Argon2。但是现在坚持BCrypt。它更简单,经过实战考验。
BCrypt的主要问题是配置其参数:cost
值。它直接影响计算单个哈希所需的时间。
基本上,这取决于您的服务器。因此,您需要在此进行一些测试,从默认成本10开始,直到需要700ms~1s来计算哈希值。
我不久前做了this handy PHP script来帮助我完成这项任务。我也为for Argon2制作了一个,但你可以看到它更复杂。
此外,永远不要供应自己的盐。让功能为您处理(即使您认为可以做得更好)。
正如在一些评论中所说,你最好的方法是添加一个新的布尔列legacy_pwd
,初始化为true。
编辑:当然不要忘记更新关于列大小的表定义。 SHA1摘要的大小为40个十六进制字符(160位),而BCrypt摘要的大小为60个字符。
此外,为了立即保护您现有的客户密码,我建议您将新的散列函数(BCrypt)应用于password
列。
当用户尝试使用其用户名/密码登录时,首先检查legacy_pwd
。
如果legacy_pwd
为true,请取bcrypt(sha1("plain_text_pwd"))
并将其与DB中的一个商店进行比较。如果匹配,则存储bcrypt("plain_text_pwd")
,将legacy_pwd
设置为false并将用户登录。
如果legacy_pwd
为false,只需将bcrypt("plain_text_pwd")
与DB中的一个商店进行比较即可。如果匹配,请将用户登录。
通常,您需要检查legacy_pwd
是否还有true
值。如果不是(所有用户都已迁移),您可以删除该列并删除处理旧密码的代码。