如果散列密码在数据库中,反派可以在登录的输入框中使用该散列密码吗?
If hashed password is in DB can villain use that hashed password in input box in login
我读到这是用于登录,密码保存内容的模块(bcrypt)。据我了解,它解决的主要问题是,如果黑客可以访问您的数据库并且您不散列密码,黑客可以轻松复制和粘贴用户名和密码并访问该帐户。该模块提供了比较散列字符串和通过req.body.password
发送的密码的方法。
我对散列的理解是,它需要一个文本并创建一个长串随机字符。在应用程序中,该字符串存储在mongoDB password
字段中,如何防止黑客将随机字符串复制并粘贴到输入框中并像这样登录?所以我没有看到散列的意义。
入门
好的,让我们先看看到底发生了什么(在最佳情况下,虽然稍微简化了):
- 用户创建新密码。
- 应用程序对密码进行哈希处理,并保留经过哈希处理的密码以供进一步读取
- 如果用户登录,应用程序将获取用户提供的密码,通过 bcrypt 运行它,bcrypt对此密码进行哈希处理,然后将此哈希密码与存储的密码进行比较。如果它们匹配,则通过登录提供的密码与密码创建期间提供的密码相同 - 这是您唯一需要知道的事情。
因此,明确这一点后,我们必须查看不同的攻击场景。
攻击者获得了对数据库的读取访问权限
好的,攻击者获得了对数据库的读取访问权限。够糟糕的。个人数据泄露。实际上,他可以复制所有数据。但是,让我们将其放在一边,看看密码。攻击者可能会看到类似这样的内容
Username Password
admin $2a$04$acaUVljoRAvazzj6YX7K2eEfUt9PHVVgr.ahZ4xLzb9292u4Bv9Sm
jdoe $2a$04$cTUGYHixAGwdTU90XflsI.G2FQuj/p4nVYW2Tp3HsCeUGs5MPmR.e
现在,哈希函数被认为是加密安全的,当且仅当暴力破解是从哈希值计算输入数据的最简单方法时。以今天的哈希大小和计算能力,您需要很长时间才能从其哈希计算密码。
按照上述过程,虽然我们的攻击者对数据库具有读取访问权限,但他不能简单地获取哈希值并将其粘贴为密码 - 应用程序将获取哈希,再次对其进行哈希处理,随后的匹配检查将失败。好处?
- 在正常操作期间,即使是管理员也无法读取用户选择的密码。人们倾向于在多个实例上使用密码。我们都知道我们不应该,但它发生了。您是否希望SO管理员知道您选择的密码?;)攻击者少了多少?
- 由于攻击者将无法通过获取哈希值来登录,因此他无法代表合法用户执行某些操作,例如购买某些东西。
- 如果攻击者想要暴力破解哈希值以获得明文密码,他将不得不投入大量资源。给你一个印象:假设我们可以做 65536 个哈希/秒,我们有 2232 种可能性,所以我们需要 ~ 2.18*1062年来暴力破解哈希,这大约是宇宙年龄的 1.59*1052 倍。即使有很多内核进行并行处理(比如说整个行星系统都转换为计算机),也需要非常、非常、非常长的时间。
- 攻击者将无法识别相同的密码,因为使用 bcrypt,即使是相同的输入数据也不会产生相同的哈希值——这是一种非常高级的哈希算法。上面的两个哈希是从相同的输入创建的。这是有效的,因为每个哈希都包含自己的(伪随机生成的,iirc)盐。这将迫使攻击者对每个找到的盐值进行暴力攻击,以识别相同的值或明文值。
,我们使获得读取访问权限的攻击者无法仅通过查看哈希值(它们似乎是 bcrypt 哈希值)来获取有关密码的任何信息。
攻击者获得了对数据库的写入访问权限
好了,你被打了。攻击者获得了写入权限。他可以对您的应用程序造成严重破坏,复制所有数据并在之后将其删除。希望你有备用电流和工作。
现在,他可以简单地为"admin"和"jdoe"设置一个新的bcrypt哈希,他可以做这些用户可以做的任何事情。
但让我们看看他不能做什么:与读取访问权限一样,他无法从给定的哈希计算明文密码。因此,即使用户使用与应用程序中相同的密码,攻击者也不会获得访问用户的Maskbook,Gibber或Instanonsense帐户的风险。
结论
通过存储 bcrypt 密码哈希,我们有几个优点:
- 密码对管理员隐藏
- 即使攻击者获得哈希值,也无法轻松计算明文密码
- 攻击者无法对相同的密码进行任何扣除,因为即使输入相同,每个输入值也会产生不同的哈希值。所以他必须对每个盐值做一个蛮力。见上文。
- 当攻击者仅获得读取访问权限时,他无法获得对应用程序的访问权限。
希望这能清楚地说明存储散列密码的优势。
正如您所说,该函数将创建从传递给它的字符串的哈希值。哈希不是随机的,而是随机输入,使用相同的算法和输入结果将是相同的,并且无法解码。如果尝试散列散列密码会产生完全不同的东西。
md5('password') = '5f4dcc3b5aa765d61d8327deb882cf99'
md5('5f4dcc3b5aa765d61d8327deb882cf99') = '696d29e0940a4957748fe3fc9efd22a3'
当用户想要登录时,他需要发送原始密码。然后,应用程序将再次计算密码的哈希值,并将其与存储的哈希值进行比较。如果用户发送哈希,应用程序将再次计算哈希,并且它与数据库中的值不匹配。
也许你的困惑来自于使用JavaScript,这表明你计算了哈希客户端。哈希应该在服务器端完成,一个人通过互联网发送原始密码而不是哈希。
好吧,如果您的密码,用户名和哈希字符串存储在数据库中,那么是的,黑客可以使用该哈希来解密所有内容。但是,如果有人嗅探您的登录名/连接,那么他们不会以纯文本形式获得您的用户名和密码,也不会获得哈希键。
- 密码输入键脚本在首次使用后无法工作
- 密码输入启动 JavaScript
- 使用复选框切换密码输入(由于安全风险而不起作用)
- 密码输入不起作用的Javascript模糊
- 如何将此文本输入文本更改为密码输入?拉拉维尔
- 是什么使浏览器自动填充电子邮件/密码输入
- 正在使用Javascript来验证“确认密码”输入,增加了任何安全风险
- 使用onclick函数将JavaScript值连续输入到密码输入中
- 自动填充(安卓chrome)上的密码输入字段长度=0
- 检查密码输入以启用按钮的Javascript
- 如何通过在登录视图的密码输入字段中按enter键来调用函数
- 带提示的HTML密码输入
- 启动密码输入切换功能不工作
- 验证密码输入类型框上的输入是否正确,显示将链接到另一个页面的按钮
- 如何显示密码在明文密码输入字段时,标签被用作值
- 在安装时将用户登录/密码输入存储在Greasemonkey脚本中
- JQuery UI对话框:导致冻结的密码输入
- 延迟的密码输入屏蔽,javascript/jquery中的android风格
- 在密码输入中使用必需的属性
- 将密码输入从项目符号更改为方框