database 在数据库中存储密码的最佳方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1054022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 07:22:50  来源:igfitidea点击:

Best way to store password in database

databasesecuritypasswords

提问by Crash893

I am working on a project that has to have authentication (username and password)

我正在开发一个必须进行身份验证(用户名和密码)的项目

It also connects to a database, so I figured I would store the username and password there. However, it seems like not such a good idea to have passwords as just a text field in a table sitting on the database.

它还连接到数据库,所以我想我会在那里存储用户名和密码。但是,将密码作为数据库表中的文本字段似乎不是一个好主意。

I'm using C# and connecting to a 2008 express server. Can anyone suggest (with as many examples as possible) what the best way to store this type of data would be?

我正在使用 C# 并连接到 2008 Express 服务器。任何人都可以建议(尽可能多的例子)存储此类数据的最佳方式是什么?

P.S I am open to the idea that this info not be stored in the database if a good reason can be provided

PS,如果可以提供充分的理由,我愿意接受不将这些信息存储在数据库中的想法

采纳答案by Paolo Bergantino

You are correct that storing the password in a plain-text field is a horribleidea. However, as far as location goes, for most of the cases you're going to encounter (and I honestly can't think of any counter-examples) storing the representationof a password in the database is the proper thing to do. By representation I mean that you want to hash the password using a salt (which should be different for every user) and a secure 1-way algorithm and store that, throwing away the original password. Then, when you want to verify a password, you hash the value (using the same hashing algorithm and salt) and compare it to the hashed value in the database.

您是正确的,将密码存储在纯文本字段中是一个可怕的想法。但是,就 location 而言,对于您将遇到的大多数情况(老实说,我想不出任何反例)在数据库中存储密码的表示是正确的做法。通过表示,我的意思是你想使用盐(每个用户应该不同)和安全的单向算法来散列密码并存储,扔掉原始密码。然后,当您想要验证密码时,您可以对值进行散列(使用相同的散列算法和盐)并将其与数据库中的散列值进行比较。

So, while it is a good thing you are thinking about this and it is a good question, this is actually a duplicate of these questions (at least):

因此,虽然您正在考虑这是一件好事,这是一个好问题,但这实际上是这些问题的重复(至少):

To clarify a bit further on the salting bit, the danger with simply hashing a password and storing that is that if a trespasser gets a hold of your database, they can still use what are known as rainbow tablesto be able to "decrypt" the password (at least those that show up in the rainbow table). To get around this, developers add a saltto passwords which, when properly done, makes rainbow attacks simply infeasible to do. Do note that a common misconception is to simply add the same unique and long string to all passwords; while this is not horrible, it is best to add unique salts to every password. Read this for more.

为了进一步澄清一点,简单地散列密码并存储的危险在于,如果侵入者控制了您的数据库,他们仍然可以使用所谓的彩虹表来“解密”密码(至少那些出现在彩虹表中的密码)。为了解决这个问题,开发人员在密码中添加了,如果做得好,彩虹攻击就变得不可行了。请注意,一个常见的误解是简单地向所有密码添加相同的唯一长字符串;虽然这并不可怕,但最好为每个密码添加独特的盐。阅读本文了解更多信息。

回答by joej

BackgroundYou never ... really ... need to know the user's password. You just want to verify an incoming user knows the password for an account.

背景您永远...真的...需要知道用户的密码。您只想验证传入的用户是否知道帐户的密码。

Hash It:Store user passwords hashed (one-way encryption) via a strong hash function. A search for "c# encrypt passwords" gives a load of examples.

散列它:通过强大的散列函数存储散列(单向加密)的用户密码。搜索“c# encrypt passwords”会提供大量示例。

See the online SHA1 hash creatorfor an idea of what a hash function produces (But don't use SHA1 as a hash function, use something stronger such as SHA256).

请参阅在线 SHA1 散列创建者以了解散列函数产生的内容(但不要将 SHA1 用作散列函数,而应使用更强大的内容,例如 SHA256)。

Now, a hashed passwords means that you (and database thieves) shouldn't be able to reverse that hash back into the original password.

现在,散列密码意味着您(和数据库窃贼)不应该能够将该散列反转回原始密码。

How to use it:But, you say, how do I use this mashed up password stored in the database?

如何使用它:但是,你说,我如何使用存储在数据库中的这个混合密码?

When the user logs in, they'll hand you the username and the password (in its original text) You just use the same hash code to hash that typed-in password to get the stored version.

当用户登录时,他们会向您提供用户名和密码(在其原始文本中)您只需使用相同的哈希码对输入的密码进行哈希处理即可获得存储的版本。

So, compare the two hashed passwords (database hash for username and the typed-in & hashed password). You can tell if "what they typed in" matched "what the original user entered for their password" by comparing their hashes.

因此,比较两个散列密码(用户名的数据库散列和输入和散列的密码)。您可以通过比较哈希值来判断“他们输入的内容”是否与“原始用户输入的密码内容”匹配。

Extra credit:

额外学分:

Question:If I had your database, then couldn't I just take a cracker like John the Ripper and start making hashes until I find matches to your stored, hashed passwords? (since users pick short, dictionary words anyway ... it should be easy)

问题:如果我有你的数据库,那么我就不能像开膛手约翰这样的破解者开始制作哈希,直到找到与你存储的哈希密码匹配的密码吗?(因为用户无论如何都会选择简短的字典词......这应该很容易)

Answer:Yes ... yes they can.

回答:是的……是的,他们可以。

So, you should 'salt' your passwords. See the Wikipedia article on salt

所以,你应该“加盐”你的密码。请参阅维基百科关于盐的文章

See "How to hash data with salt" C# example

请参阅“如何使用盐散列数据”C# 示例

回答by nilamo

As a key-hardened salted hash, using a secure algorithm such as sha-512.

作为密钥强化的盐渍散列,使用安全算法,例如 sha-512。

回答by Mitch Wheat

The best security practice is not to store the password at all (not even encrypted), but to store the salted hash (with a unique salt per password) of the encrypted password.

最佳安全实践是根本不存储密码(甚至不加密),而是存储加密密码的加盐散列(每个密码具有唯一的盐)。

That way it is (practically) impossible to retrieve a plaintext password.

这样(实际上)不可能检索明文密码。

回答by zebrabox

I'd thoroughly recommend reading the articles Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes[dead link, copy at the Internet Archive] and How To Safely Store A Password.

我强烈建议您阅读以下文章:彩虹表足够了:您需要了解的安全密码方案[死链接,在 Internet 档案馆复制] 和如何安全存储密码

Lots of coders, myself included, think they understand security and hashing. Sadly most of us just don't.

许多编码人员,包括我自己,认为他们了解安全性和散列。可悲的是,我们大多数人都没有。

回答by Crippledsmurf

I may be slightly off-topic as you did mention the need for a username and password, and my understanding of the issue is admitedly not the best but is OpenID something worth considering?

我可能有点跑题,因为您确实提到需要用户名和密码,我对这个问题的理解诚然不是最好的,但 OpenID 值得考虑吗?

If you use OpenID then you don't end up storing any credentials at all if I understand the technology correctly and users can use credentials that they already have, avoiding the need to create a new identity that is specific to your application.

如果您使用 OpenID,那么如果我正确理解该技术并且用户可以使用他们已经拥有的凭证,那么您最终根本不会存储任何凭证,而无需创建特定于您的应用程序的新身份。

It may not be suitable if the application in question is purely for internal use though

如果所讨论的应用程序仅供内部使用,则可能不适合

RPXprovides a nice easy way to intergrate OpenID support into an application.

RPX提供了一种很好的简单方法来将 OpenID 支持集成到应用程序中。

回答by Ray Lu

In your scenario, you can have a look at asp.net membership, it is good practice to store user's password as hashed string in the database. you can authenticate the user by comparing the hashed incoming password with the one stored in the database.

在您的场景中,您可以查看 asp.net 成员资格,将用户密码作为散列字符串存储在数据库中是一种很好的做法。您可以通过将散列的传入密码与存储在数据库中的密码进行比较来验证用户。

Everything has been built for this purposes, check out asp.net membership

一切都是为此目的而构建的,请查看asp.net 会员资格

回答by waiwai933

I would MD5/SHA1 the password if you don't need to be able to reverse the hash. When users login, you can just encrypt the password given and compare it to the hash. Hash collisions are nearly impossible in this case, unless someone gains access to the database and sees a hash they already have a collision for.

如果您不需要能够反转散列,我会使用 MD5/SHA1 密码。当用户登录时,您只需加密给定的密码并将其与哈希值进行比较。在这种情况下,哈希冲突几乎是不可能的,除非有人获得了对数据库的访问权限并看到了他们已经发生冲突的哈希。