防止用户使用一个电子邮件地址创建多个帐户?

Prevent user from creating multiple accounts with one e-mail address?

假设用户正在网站上创建帐户。用户提供的电子邮件地址保存在 mysql 中,但在保存前进行了哈希处理。这样,可能的黑客就不会看到电子邮件地址。但另一方面,对我或你 ("the programmer") 而言,无法查看用户是否试图使用相同的电子邮件地址创建帐户(我真的想阻止)。

问题:总的来说,您对解决这个问题有什么建议?有任何建议或解决方案吗?

问题:在对电子邮件地址进行哈希处理时,一个帐户会不会更多"secure"?

P.S。仅供参考,此应用程序使用 PHP 作为服务器语言。

更新:

  1. 我使用带有 PHP 内置盐的 BCRYPT。
  2. 我用mysqli.

当您对电子邮件进行哈希处理以将其插入数据库时​​,请检查此类经过哈希处理的电子邮件是否已经存在,就像您在每次用户登录时检查它一样。

如果您对所有内容进行哈希处理,帐户会更安全,但那样的话就很难recover/reset丢失username/password,因为您不知道要将重置信息发送到哪个电子邮件地址

onblur 事件对用户输入的电子邮件 ID 进行哈希处理,并检查它是否存在于 mysql 电子邮件列中,如果存在,它将导致一行然后禁用按钮,否则允许用户插入

使用 select * 来自电子邮件地址="hashed(email_id_entered)"

的用户

如果(结果>0) 禁用按钮 别的 启用

正如 S.L Barth 所说,您可以按照给定的方式对电子邮件地址进行哈希处理,也许在字段失去焦点后使用 ajax 请求,然后检查该哈希值是否存在于数据库中,如果返回的行数 > 0 那么 javascript 可以输出一条消息,说明该帐户已经注册。

在 table 上创建唯一索引也可行,但这不会反馈问题,直到尝试将数据写入数据库,这可能为时已晚。最终用户无需循环。

更新

如果您的电子邮件地址经过加盐处理后无法根据再次添加的同一电子邮件地址进行确认,那么如果无法解密,存储该电子邮件地址的意义何在?修改你的方法。使用 php 函数,例如 Password_hash()password_verify()

解决方案 #1 - MySQL 方法

email 列上添加 unique 索引。这将防止添加具有相同 email 字段的任何其他行。没有错误,顺利。

假设您的 table 是 users 并且您将电子邮件存储在 email_hashed 中:

ALTER TABLE users
ADD UNIQUE (email_hashed)

如果您已经有重复项,则需要先清洁后再应用。

.

解决方案 #2 - PHP 方法

简单地散列电子邮件和SELECT数据库中所有具有该散列的行。像那样:

$email = 'ex@example.com';
$hashed = someHashing($email);
$sql = ("SELECT id FROM users WHERE email_hashed = '$email'");
..

如果要获取任何行,那么您可以执行显示消息、错误或其他任何操作。


我建议同时使用这两种解决方案。

编辑 - 关于...BCrypt...

是的,您正在使用 BCrypt。如果您想散列电子邮件,有两种方法可供您使用(不知道为什么,但无论如何!)。一个会被大家笑话的那个,那个更好。

第一个(可笑)是:

  1. SELECT 来自整个数据库 table 以及每个可能存在的电子邮件散列
  2. 运行 foreach() {} 遍历数据库中的每个散列
  3. 在每个循环中使用 password_verify()
  4. 比较哈希
  5. 如果有任何比较 returns true 那么 运行 你自己的一些代码

第二个很简单:

  • 将散列更改为 md5(使用 md5('text') 函数)或 sha256 以获得更长的散列(使用 hash('sha256','text')

另一个编辑

Question: Would an account be more "secure" when hashing the e-mail address?

我认为在 Whosebug 上提出问题不是问题,但由于 "a bonus" 我会在这里提出一些想法。

虽然我不是安全专家,所以我可能不知道某些事情。

无论如何,使用 BCrypt 散列密码并确保帐户上的任何内容都可以 任何 不需要密码的方式进行编辑(例如有缺陷的 API 或受损的管理仪表板)。我认为您还应该保护易受攻击的数据(如姓名、地址、phone 号码等)免受 public 访问。

散列电子邮件有我能想到的唯一目的。万一成功破解,倾倒了您所有数据库的人将不会获得任何一个电子邮件地址。那很好。但它也会阻止您发送时事通讯、帐户到期通知和其他重要电子邮件。

在 90% 的网站中,我会说 "hashing emails, are you insane?",但如果您根本不需要重复使用电子邮件(除了注册电子邮件,您永远不会发送任何电子邮件)并且希望用户电子邮件发送至非常安全,那么是的,散列可以证明是有用的。但是请不要 BCrypt :P