存储用户并传入单表或单表

我想为我的网站创建一个用户管理系统,

I want to create a user management system for my site ,

什么对安全性和性能更好.

what is better for security and performance .

类型 1:

table_user : user_id , user_name , user_email , user_password . user_phone ...

类型 2:

table_user : user_id , user_name , user_email ...
table_pass : user_id , user_password .
table_phone: user_id , user_phone .

哪个更好?

推荐答案

理想情况:

  • 根本不要存储密码(即使是加密的).存储从密码派生的哈希.
  • Salt 密码以防止彩虹攻击.
  • 将哈希放在一个单独的数据库服务器上,在它自己的防火墙和它自己定义良好的 API 之后1.这个 API 应该只做三件事:
  • Don't store passwords at all (even encrypted). Store hashes derived from passwords.
  • Salt the passwords to prevent rainbow attacks.
  • Put hashes on a separate database server, behind its own firewall and its own well-defined API1. This API should do only three things:
  1. 对于给定的用户名,检索相应的密码哈希.
  2. 对于给定的用户名,设置新的哈希值(以支持重置密码).
  3. 删除给定的用户名及其哈希值(以支持用户注销).

  • 对盐做同样的事情:将它们放在自己的服务器上,并在自己的防火墙和 API 之后.这个 API 应该只做三件事:

  • Do the same for salts: put them on their own server and behind their own firewall and API. This API should do only three things:

    1. 对于给定的用户名,检索相应的盐.
    2. 对于给定的用户名,将新盐设置为随机值(以支持重置密码).
    3. 删除给定的用户名及其盐(以支持用户注销).

  • hash 和 salt 服务器都应该与外界(以及彼此之间)隔绝,并且只能从运行您的 Web 应用程序的服务器(即 PHP 或 ASP.NET 或其他任何...)访问.
  • 当用户尝试通过输入用户名和密码登录时:

    When user tries to log-on by entering username and password:

    • 确保这是通过 HTTPS 完成的,以便输入的数据安全地到达您的服务器.
    • 调用 API 来检索用户名的密码哈希.
    • 调用为用户名检索盐的 API.
    • 对用户输入的密码进行加盐和哈希处理,并将其与检索到的哈希值进行比较.
    • 如果匹配,则授予用户访问权限.

    就其性质而言,散列是不可逆的——除了用户之外,没有人知道确切的密码,甚至你也不知道.如果用户忘记密码,您不能将密码发送给他们,但您可以允许他们重置密码,前提是他们通过了一些额外的验证(即可以访问特定的电子邮件地址和/或回答秘密问题).

    By their nature, hashes are irreversible - other than the user, nobody, not even you, knows the exact password. In case the user forgets the password, you can't send the password to them, but you can allow them to reset the password assuming they pass some additional verification (i.e. have access to a particular e-mail address and/or answer a secret question).

    顺便说一句,登录是一种相对的操作,因此除非您完全忽略正确的索引,否则不太可能造成性能瓶颈.

    BTW, log-on is a relatively rare operation, so it's unlikely to pose a performance bottleneck unless you completely disregard proper indexing.

    1 例如实现一个 Web 服务,然后只打开该 Web 服务所需的端口,不打开其他任何东西.

    1 E.g. implement a Web Service, then open only the port needed for that Web Service and nothing else.

    相关文章