如何在不将密码保存在数据库中的情况下验证用户身份

Posted

技术标签:

【中文标题】如何在不将密码保存在数据库中的情况下验证用户身份【英文标题】:how to authenticate users without saving passwords in database 【发布时间】:2015-04-23 03:04:59 【问题描述】:

我正在开发一个银行演示应用程序。在我所在的地区,用户登录他们的银行网站并根据他们拥有的两个字段进行一些交易(您可以假设两个密码——我们称之为 cvv2 和 Second-Password)。这两个密码仅用于互联网或移动交易。

我确信他们不会将这些密码保存在数据库中;因为如果他们将这些密码保存在数据库中,那么数据库管理员可以在没有真实用户权限的情况下使用它们并进行虚假交易。

顺便问一下,当银行及其网站没有将这些密码保存在数据库中时,银行及其网站如何验证用户身份并检查输入的字段(这两个密码)是否正确。

【问题讨论】:

当然,它们以一种或另一种方式存储在数据库中。如何进行身份验证。与生活的其他部分一样,银行业务基于信任 根据 PCIDSS,银行系统不应将字段、字段的一部分或它们的任何组合存储在数据库中。 pcisecuritystandards.org/security_standards 加密它们。但他们在那里,作为内部人员,它可以被打破 无论如何,如果一个 dba 只是执行一个 sql 查询 【参考方案1】:

我对此并不陌生,但找到了一种不将密码存储在数据库中并仍然对用户进行身份验证的方法。

您可以创建用户名和密码的有效负载,例如“用户名 + 密码”,然后使用 bcrypt 或任何其他算法对其进行哈希处理。

将此哈希值与用户名字段一起存储在数据库中。 这样,密码就不会存储在任何地方了。

下次您想要进行身份验证时,您可以获取用户名和密码并从中生成哈希值并匹配数据库中存在的内容。只有正确的密码才会产生相同的哈希值。

如果我错了,请纠正我。

【讨论】:

嗯,你的逻辑有几个缺陷: 1. 你做的基本上和在数据库中存储密码一样,你只是添加一个用户名。 2.您将密码和用户名存储在同一列中,这是一种不好的做法,即使该字段是散列的。 3. 您的解决方案无法根据用户名执行数据库查询,因为您知道......任何地方都没有存储实际的用户名。 1. true 2. 你能帮我理解为什么这不是好的做法,它是一种新的做法。这有什么问题? 3. 用户名将存储在一个列中。该表将如下所示: |用户名 | hashed_username+password |【参考方案2】:

当今的大多数银行系统不依赖简单的密码,它们具有两因素身份验证。例如,这可能是一个使用您的信用卡生成代码的独立设备,或者至少是一个 TAN 列表。

当他们存储密码(通常与其他安全措施结合使用)时,您可以确定他们存储了密码的散列。哈希是单向的,您无法从中取回原始密码。用于存储密码的良好哈希算法是 BCrypt、PBKDF2 或 SCrypt,因为它们提供了成本因素。如果您有兴趣阅读有关该主题的更多信息,可以查看我的tutorial abour 安全存储密码。

【讨论】:

如果我们存储散列,问题不会解决。因为我们仍在使用数据库中的哈希值检查用户输入密码的哈希值。所以 db admin 可以创建虚假请求并发送哈希,以便检查器功能无法确定真实用户是否发送它 @HuseinBehbudiRad - 不,他不能。检查器功能需要原始密码并自行计算哈希,然后比较哈希。由于几乎不可能找到导致相同哈希的密码,因此管理员无法发送虚假请求。

以上是关于如何在不将密码保存在数据库中的情况下验证用户身份的主要内容,如果未能解决你的问题,请参考以下文章

如何在不将旧根保存在堆栈中的情况下切换到新根?

如何在不关闭当前 Firebase 会话的情况下创建用户身份验证 [重复]

如何在不将 csv 保存到磁盘的情况下将 csv 格式的数据从内存发送到数据库?

如何在不传递用户名和密码的情况下获得salesforce Sessionid?

如何在不经过注册用户身份验证的情况下保护公共API请求

在不使用 Firebase 的情况下使用电子邮件和密码进行 Flutter 身份验证