简体   繁体   English

处理用户帐户身份验证和密码的最佳方法

[英]Best way to handle user account authentication and passwords

What is the best way to handle user account management in a system, without having your employees who have access to a database, to have access to the accounts. 在没有有权访问数据库的员工的情况下,在系统中处理用户帐户管理的最佳方法是什么才能访问帐户。

Examples: 例子:

  1. Storing username/password in the database. 在数据库中存储用户名/密码。 This is a bad idea because anyone that has access to a database can see the username and password. 这是个坏主意,因为任何有权访问数据库的人都可以看到用户名和密码。 And hence use it. 因此使用它。

  2. Storing username/password hash. 存储用户名/密码哈希。 This is a better method, but the account can be accessed by replacing the password hash in the database with the hash of another account that you know the auth info for. 这是一种更好的方法,但可以通过使用您知道其身份验证信息的另一个帐户的哈希值替换数据库中的密码哈希来访问该帐户。 Then after access is granted reverting it back in the database. 然后在授予访问权限后将其还原回数据库中。

How does windows/*nix handle this? windows / * nix如何处理这个?

This is a better method, but the account can be accessed by replacing the password hash in the database with the hash of another account that you know the auth info for. 这是一种更好的方法,但可以通过使用您知道其身份验证信息的另一个帐户的哈希值替换数据库中的密码哈希来访问该帐户。

There's really no way around this. 真的没办法解决这个问题。 Anyone who as write access to the password file has complete control of the computer. 任何对密码文件具有写入权限的人都可以完全控制计算机。

I'd go with 2 but use some salt. 我跟2去,但要用盐。 Some pseudocode: 一些伪代码:

SetPassword(user, password)
    salt = RandomString()
    hash = Hashfunction(salt+password)
    StoreInDatabase(user, salt, hash)

CheckPassword(user, password)
    (salt, hash) = GetFromDatabase(user)
    if Hashfunction(salt+password) == hash
        return "Success"
    else
        return "Login Failed"

It is important to use a well known hash function (such as MD5 or SHA-1), implemented in a library. 使用在库中实现的众所周知的散列函数(例如MD5或SHA-1)非常重要。 Don't roll your own or try implementing it from a book its just not worth the risk of getting it wrong. 不要自己动手或尝试从书中实现它,不值得冒错的风险。

@Brian R. Bondy: The reason you use salt is to make dictionary attaks harder, the attacker can't hash a dictionary and try against all the passwords, instead she have to take the salt + the dictionary and hash it, which makes the storage requierments expode. @Brian R. Bondy:你使用salt的原因是为了让字典变得更难,攻击者无法对字典进行散列并尝试反对所有密码,而是必须使用salt +字典并将其哈希,这使得存储需求expode。 If you have a dictionary of the 1000 most commaon passwords and hash them you need something like 16 kB but if you add two random letters you get 62*62*16 kB ≈ 62 Mb. 如果您有1000个最常用密码的字典并对它们进行哈希处理,则需要16 kB,但如果添加两个随机字母,则得到62 * 62 * 16kB≈62Mb。

Else you could use some kind of One-time passwords I have heard good things about OTPW but havent used it. 否则你可以使用某种一次性密码我听说过有关OTPW的好东西但没有使用它。

This was a common issue in UNIX many years ago, and was resolved by separating the user identity components (username, UID, shell, full name, etc.) from the authentication components (password hash, password hash salt). 这是多年前UNIX中的一个常见问题,通过将用户身份组件(用户名,UID,shell,全名等)与身份验证组件(密码哈希,密码哈希盐)分开来解决。 The identity components can be globally readable (and in fact must be, if UIDs are to be mapped to usernames), but the authentication components must be kept inaccessible to users. 标识组件可以是全局可读的(实际上必须是,如果要将UID映射到用户名),但是用户必须保持身份验证组件不可访问。 To authenticate a user, have a trusted system which will accept a username and password, and will return a simple result of "authenticated" or "not authenticated". 要对用户进行身份验证,请拥有一个可信系统,该系统将接受用户名和密码,并返回“已验证”或“未经过身份验证”的简单结果。 This system should be the only application with access to the authentication database, and should wait for a random amount of time (perhaps between 0.1 and 3 seconds) before replying to help avoid timing attacks. 该系统应该是唯一可以访问身份验证数据库的应用程序,并且应该在回复之前等待一段随机时间(可能在0.1到3秒之间)以帮助避免计时攻击。

You could use openID and save no confidential user passwords at all. 您可以使用openID并且根本不保存任何机密用户密码。 Who said it is for websites only? 谁说它只适用于网站?

Jeff Atwood has some good posts concerning hashing, if you decide to go that route: 如果你决定走这条路,杰夫阿特伍德有一些关于哈希的好帖子:

  1. A very bad idea indeed. 确实是个坏主意。 If the database is compromised, all accounts are compromised. 如果数据库遭到入侵,则所有帐户都会受到损害。
  2. Good way to go. 好的方式去。 If your hash algorithm includes the username, replacing the password hash with another one will not work. 如果您的哈希算法包含用户名,则用另一个密码哈希替换密码哈希将不起作用。

Unix stores hashes in aa text file /etc/shadow, which is accessible only to privileged users. Unix存储文本文件/ etc / shadow中的哈希值,只有特权用户才能访问。 Passwords are encrypted with a salt. 密码用盐加密。

This is a bit of a non problem for a lot of applications because gaining access to the database is probably the most common goal of any attacker. 对于许多应用程序来说这是一个非问题,因为获得对数据库的访问可能是任何攻击者最常见的目标。 So if they already have access to the database why would they still want to login to the application ? 因此,如果他们已经可以访问数据库,为什么他们仍然想要登录到应用程序? :) :)

If the 'system' is a public website RPX can provide you with a login/user account services for the most common providers, like OpenId, Facebook, Google, etc. 如果'系统'是公共网站, RPX可以为最常见的提供商提供登录/用户帐户服务,如OpenId,Facebook,Google等。

Now, given the way you formulate your question I guess the 'system' you're talking about is more likely an internal windows/linux based enterprise app. 现在,考虑到你制定问题的方式,我猜你所谈论的'系统'更可能是一个基于Windows / Linux的内部企业应用程序。 Nevertheless; 尽管如此; for those googling around for login/user account providers (like I did before a came across RPX), this could be a good fit :) 对于那些在网上搜索登录/用户帐户提供商的人(就像我在遇到RPX之前所做的那样),这可能是一个很好的选择:)

You could store the salt for the hashed password in another table, of course each user would have their own salt. 您可以将哈希密码的存储在另一个表中,当然每个用户都有自己的盐。 You could then limit access to that table. 然后,您可以限制对该表的访问。

The usual approach is to use option two with email: 通常的方法是使用选项二和电子邮件:

Store user name, password hash and email address into the database. 将用户名,密码哈希和电子邮件地址存储到数据库中。

Users can either input their password or reset it, in the latter case a random password is generated, a new hash is created for the user and the password is sent to him via email. 用户可以输入密码或重置密码,在后一种情况下,会生成随机密码,为用户创建新的哈希,并通过电子邮件将密码发送给他。

Edit: If the database is compromised then you can only guarantee no sensible information can be accessed, you can no longer ensure the security of your application. 编辑:如果数据库被泄露,那么您只能保证无法访问合理的信息,您无法再确保应用程序的安全性。

Hash the username and the password together . 将用户名和密码混合在一起 That way, if two users have the same password, the hashes will still be different. 这样,如果两个用户具有相同的密码,则哈希值仍然不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM