我负责在我们的 .Net MVC 4 Web 应用程序中进行身份验证,我遇到了密码散列、存储和身份验证方面的问题。
目前计划使用 2 个 Salts,1 个动态(每个用户)和 1 个静态(Web 应用常量)和一个强大的哈希函数。
给定一个包含用户名和密码的简单用户表:
- 我是否将每个用户的 salt 存储在用户表的列中?
我担心的是,如果这样做,我将不得不从 Web 应用程序内存中的数据库中仅获取用户的用户名。是否存在某种可能存在问题的攻击? 理想情况下,我希望这是一个一步/一个 SQL 请求身份验证。
我是不是多虑了?是否有“每用户”salt 的替代方案,我仍然可以在其中进行一步验证?
最佳答案
盐可以与密码哈希一起存储,因此您可以为每个密码而不是每个用户创建一个盐。密码哈希函数(如 BCrypt 或 PBKDF2 的慢 key 派生函数)的常见做法是将盐明文作为密码哈希的一部分返回,这意味着您可以将盐和哈希一起存储在单个数据库字段中。
要验证输入的密码,您首先必须搜索密码哈希(使用用户名或电子邮件),然后该函数可以从存储的密码哈希中提取使用过的盐,并用它来比较哈希。这实际上应该回答你的问题,数据库通常没有适当的函数来散列密码,所以你不能在 SQL 查询中进行验证,验证将在代码中完成。
第二种盐实际上叫做胡椒,添加这个服务器端 secret 的最好方法是用这个 secret 加密已经散列的密码。与哈希相比,这将是一种双向加密,允许在必要时交换 key 。
关于database - 在哪里存储密码盐以及如何获取它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17551419/