我有一个数据库,其中的密码列使用sha1值。我打算将我的加密方法更新为Bcrypt或sha256。想获得一个脚本,该脚本会将所有sha1密码更新为sha256或Bcrypt值。非常感谢
示例: 如果我的密码是hari
sha1
给出
46ebaaa2b80c7a3459b80353e085aaeed5aff2ff
sha256
给出
f7b3781c5eafc2779a96bae2e4875a83ecce46f198e9f81916521d9d218c7da7
我该如何将所有sha1更改为sha256
答案 0 :(得分:2)
在其他答案或评论中已经说了很多。
基本上,您不能简单地从哈希值移动到与初始值相对应的另一个哈希值。哈希函数是一种单向函数。
但是不要害怕,有希望!这是一种允许您进行以下操作的方法:
这很重要。请仔细阅读。
对于密码存储,您应该不使用任何(加密的)哈希函数,例如SHA1,SHA2甚至SHA3(Keccak)。主要原因是它们速度很快。太快。密码散列并不是您应该追求的目标。 More information。
而且他们不处理盐腌,这意味着您将需要手动进行盐腌,这意味着您更有可能将其弄乱。
对于密码存储,您需要为此专用的密码哈希函数。您有几个众所周知的功能:PBKDF2,BCrypt,SCrypt或Argon2。
这些函数可以处理盐并且很慢(并且性能可以通过参数进行调整)。
现在,由于您使用的是PHP,因此对您来说更加简单。 password_hash()
函数为您提供了一个不错的蝙蝠右键,并且可以正常工作。用它!
如果您使用的是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
为真,则取bcrypt(sha1("plain_text_pwd"))
并将其与数据库中的一个存储进行比较。如果匹配,则存储bcrypt("plain_text_pwd")
,将legacy_pwd
设置为false并登录用户。
如果legacy_pwd
为假,只需取bcrypt("plain_text_pwd")
并将其与数据库中的一个存储进行比较。如果匹配,请登录用户。
通常,您需要检查legacy_pwd
是否还有剩余的true
值。如果不是这样(所有用户都已迁移),则可以删除该列并删除处理旧密码的代码。
答案 1 :(得分:0)
由于哈希操作不可逆,因此无法更改哈希值。也就是说,您可以将纯文本转换为哈希值,但不能相反。
因此,一个更好的主意是为sha256密码创建一个不同的表。下次登录时,请继续将您的用户移植到其他表。
即,下一次用户登录时,从现有表中检查密码是否正确。如果发现用户正确,则使用sha256重新哈希密码并将其保存到另一个(新)表中。最终,通过这种方式,当用户登录时,您可以将其移植到更安全的sha256哈希密码。
移植用户后,您可以从较早的表中删除其条目(在那时或之后通过任何批处理脚本删除)。
现在介绍如何处理登录。在移植所有用户之前,这将是一个两步过程。
1.首先签入较新的表。如果发现没问题,请继续进行。
2.否则请检查旧表。