php - 加密密码时随机 128 位辣椒
问题描述
我正在使用 PHP 7.2 开发一个新的 Web 应用程序,并且我正在考虑采用以下方法来最大限度地提高密码的安全性。这是我打算做的事情:
- 一个 PHP 文件包含一个包含 100 个 128 位长度的常量标记的数组(在开始时随机生成)
- 当用户注册时
- 伪随机从数组(
array_rand()
)中挑一个辣椒,并将索引存入SQL数据库 hash_hmac("sha256", $password, $pepper);
使用(其中$pepper
是预定义列表中的随机 128 位字母数字令牌)加密密码字符串- 使用 Argon2i 对密码进行哈希处理(argon2id 不适用于我的服务器)
- 伪随机从数组(
- 当用户登录时
- 要检查密码,请取出辣椒,再次加密密码并匹配它:
password_verify(hash_hmac("sha256", $_POST["password"], $pepper), $row["password"])
- 要检查密码,请取出辣椒,再次加密密码并匹配它:
您认为这种使用辣椒的方法有效地提高了安全性吗?是否存在任何潜在的缺陷和漏洞,特别是 PHP?
我在几个论坛上看到其他人建议使用特定于系统的常量(例如,服务器的硬件+软件配置所独有的东西),仅使用单个辣椒等。我实现这一点的目的是,如果攻击者成功获得使用 SQL 注入的用户数据库(例如),他们可能仍然无法访问我的peppers.php
代码。我认为使用一个辣椒很容易被暴力破解。我喜欢我的想法的一点是,我总是可以在多台服务器上扩展这个算法,或者自由地增加预定义的辣椒。
解决方案
这更多是关于 IT 安全或密码学,但我们假设提及 PHP 就足以在 StackOverflow 上执行小型协议分析。
盐的想法是它是独一无二的。这样就无法构建彩虹表,也无法区分相同的密码。盐通常与密码散列一起存储,应该被认为是公开的。
辣椒的想法是它仍然是秘密的,因此无权访问它的攻击者无法创建密码哈希。这意味着攻击者不可能猜出密码。
现在您已经定义了一个似乎没有使用盐并且胡椒有些独特的方案。如果不是这样,那就不好了。例如,创建 100 个彩虹表似乎很昂贵但可行。此外,您将不得不存储多个辣椒/秘密,而不仅仅是一个。
创建随机的盐和胡椒(均为 128 位)比您的方案更安全。不需要 HMAC:您可以为 Argon2i 指定密钥。如果你不能,连接盐和胡椒并将它们用作盐(或者在连接上使用哈希并使用它,如果盐参数是有限的)。
推荐阅读
- python - 使用 python speech_recognition 播放和流式转录音频
- r - 使用 R 的 quanteda 情绪 wordcloud?
- ajax - Ember 适配器通过 Ajax Post 接收数据
- grafana - 如何仅在普罗米修斯的白天获得平均值
- graphql - 如何在 apollo 的 graphql-gql 中使用从 npm 包导入的自定义 graphQL 类型
- jquery - 使用 CSS 转换属性时 jQuery 动画卡顿
- awk - 根据文件中的分隔符捕获值
- javascript - Vue:显示组件取决于 API 状态
- python - 双指数平滑 (DES) 在 R 和 Python 中产生不同的结果?
- r - 如何将向量化事务转换为二进制矩阵事务