javascript - 在服务器不知道正在查询的记录的情况下查询服务器是否存在记录

标签 javascript hash passwords security

我一直在考虑诸如 pwnedlist.com 之类的服务和 shouldichangemypassword.com以及他们的根本问题 - 信任。

也就是说,用户必须相信这些服务不会收集提交的查询。

Pwnedlist.com 提供了提交用户查询的 SHA-512 哈希的选项,这是向前迈出的一步,但如果查询确实存在于数据库中,仍然会泄露信息。也就是说,恶意服务会知道给定的电子邮件地址是有效的(另请参阅:为什么您不应该单击垃圾邮件中的退订链接)。

我想出的解决方案如下:

1) 不是用户自己计算和提交哈希值,而是通过客户端 javascript 计算哈希值(我将在示例中使用更简单的 md5):

md5("user@example.com") = "b58996c504c5638798eb6b511e6f49af"

2) 现在,不是将整个散列作为查询传输到服务器,而是只传输前 N 位:

GET http://remotesite.com?query=b58996

3) 服务器响应其数据库中以相同 N 位开头的所有哈希值:

{
"b58996afe904bc7a211598ff2a9200fe",
"b58996c504c5638798eb6b511e6f49af",
"b58996443fab32c087632f8992af1ecc", 
...etc... }

4) 客户端 javascript 比较服务器返回的哈希列表,并通知用户她的电子邮件地址是否存在于数据库中。 由于服务器响应中存在“b58996c504c5638798eb6b511e6f49af”,因此电子邮件存在于数据库中 - 通知用户!

现在,这个解决方案的明显问题是用户必须相信客户端 javascript 只传输它所说的将要传输的内容。然而,知识渊博的人将能够验证查询没有被泄露(通过观察发送到服务器的查询)。这不是一个完美的解决方案,但如果用户可以(理论上)验证网站是否按其所说的那样运行,它将增加信任级别。

SO 如何看待这个解决方案?重要的是,有没有人知道任何现有的例子或对这种技术的讨论?

注意:pwnedlist.com 和 shouldichangemypassword.com 显然都是由信誉良好的人/组织经营的,我没有理由不相信。这更像是一种思维练习。

最佳答案

pwnedlist.com 等服务正在处理公共(public)信息。根据定义,每个人都可以访问这些数据,因此试图保护它是一个有争议的问题。攻击者只会从 The Pirate Bay 下载它.

但是,使用像这样的散列函数仍然很容易被破解,因为它是未加盐的并且缺乏 key 矫正。实际上,像 sha-512 这样的消息摘要函数并不是完成这项工作的正确工具。

使用 Bloom Filter 会更好.这允许您创建泄露数据的黑名单,而没有任何获得纯文本的可能性。这是因为基于排列的蛮力比真正的纯文本更可能发现冲突。查找和插入很酷 O(1) 的复杂性,表本身占用的空间要少得多,可能是使用传统 sql 数据库的空间的 1/10,000,但是这个值是可变的,具体取决于您指定的错误率.

关于javascript - 在服务器不知道正在查询的记录的情况下查询服务器是否存在记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8282299/

相关文章:

Javascript 只隐藏元素

ruby - 将 ruby​​ 数组中的哈希与其同级数组进行比较

hash - 首先是盐还是哈希?

javascript - 防止主题标签影响 Cycle2 的后退按钮

javascript - PyQt 中的评估JavaScript - 未调用函数

javascript - Cypress 模糊事件(当输入失去焦点时)不会用 headless "cypress run --browser firefox"触发,但可以与 "cypress open"一起使用

javascript - 无法使用javascript获取html元素的颜色

密码未回显到终端的 Python getpass 示例

php - 我可以检查哈希密码是否等于 laravel 中的特定值吗?

html - 受 Staticrypt 保护的 Jekyll 网站,将 encrypted.html 放在哪里?