简体   繁体   English

当密码未以纯文本形式存储在数据库中时,如何验证用户?

[英]How users are verified when passwords are NOT stored as plain text in the database?

I know it is bad to store password as plain text in DB, because if hackers gain access to the server's DB, all usernames and passwords will be completely exposed?我知道将密码以明文形式存储在数据库中是不好的,因为如果黑客获得对服务器数据库的访问权限,所有用户名和密码都会完全暴露? Therefore, original passwords are passed through hash functions, afterward they are stored in DB as series of incomprehensible characters of the same length.因此,原始密码通过hash函数,之后以一串等长的不可理解字符的形式存储在DB中。 That is a good thing for security.这对安全来说是一件好事。

But...how can the server verify if the users enter correct passwords or not?但是......服务器如何验证用户是否输入了正确的密码? Since the users enter their passwords in their original forms (eg: whoami, ilovecomputer...), but the server store them under "hashed" forms (eg: 234203409803249580980gfdg41cdvd4, jknegnergiuhiuhdni4584234dfgbn4j....).由于用户在其原始 forms(例如:whoami、ilovecomputer...)中输入密码,但服务器将它们存储在“散列”forms(例如:234203409803249580980gfdg41cdvd4、jknegnergiuhiuhdni4584234dfgbn4j...)下。 How can the user-entered password and the sever-stored password be matched?如何匹配用户输入的密码和服务器存储的密码?

Let H be a password hashing function. One simple property of these functions is that they a deterministic, ie same input outputs the same value.H为密码散列值 function。这些函数的一个简单属性是它们具有确定性,即相同的输入输出相同的值。

First time: When users register onto the website, they require the users' password, usually two fields.第一次:当用户在网站上注册时,他们需要用户的密码,通常是两个字段。 Now the password is hashed h = H(passwd) and stored in the database for the user.现在密码被散列h = H(passwd)并存储在用户的数据库中。

Later time: User enters the user name and password, then the server gets the h from the database by using the user name.稍后时间:用户输入用户名和密码,然后服务器使用用户名从数据库中获取h Hashes the currently entered password pwd , too.也散列当前输入的密码pwd if H(pwd) = h then entered password is correct.如果H(pwd) = h那么输入的密码是正确的。 Your server lets the user continue to the system.您的服务器允许用户继续使用系统。

The above are the basics of the password system, however, that is not enough.以上是密码系统的基础知识,但是,这还不够。 a little gist of the password hashing;密码散列的一些要点;

  1. For password hashing we don't use the cryptographic hashes at least directly.对于密码散列,我们至少不直接使用加密散列。 Cryptographic hashes are required to be fast, however, password hashing is required to be slow even controllably slow with adjustable iteration.密码散列需要很快,但是,密码散列需要很慢,甚至可以通过可调整的迭代来控制缓慢。 This helps to systems to fit to desired security.这有助于系统适应所需的安全性。
  2. We use salt against the rainbow attack;我们使用盐来对抗彩虹攻击; random salt per user will prevent the rainbow attacks.每个用户的随机盐将防止彩虹攻击。 We also use pepper as server salt for domain separations.我们还使用胡椒粉作为域分离的服务器盐。
  3. We require memory-hard password hashing to prevent massive GPU/ASIC/FPGA password search.我们需要内存硬密码散列来防止大量 GPU/ASIC/FPGA 密码搜索。 See hashcat for some comparison of password hashings.有关密码散列的一些比较,请参见 hashcat。
  4. Require threads against parallelization, too.也需要针对并行化的线程。
  5. We used specially designed password hashing like PBKDF2, Scrypt, Argon2.我们使用专门设计的密码哈希算法,如 PBKDF2、Scrypt、Argon2。 Argon2 was the winner of the latest password hashing competition. Argon2 是最新密码哈希竞赛的获胜者。 It is advised for everybody to use Argon2id in their new system.建议大家在新系统中使用 Argon2id。

The Final, and most important point is to educate the user about passwords.最后一点也是最重要的一点是向用户介绍密码。 Firstly, introduce then the dicewire or similar password generation methods, and secondly, introduce them to password managers like 1passwords.首先介绍dicewire或类似的密码生成方法,其次介绍给1passwords等密码管理器。

Here is how you authenticate users without storing their password in clear text.以下是如何在不以明文形式存储密码的情况下对用户进行身份验证。

You will need TWO database columns to do this.您将需要两个数据库列来执行此操作。 Column 1 - Password Hash, Column 2 - Salt第 1 列 - 密码 Hash,第 2 列 - 盐

Column 2 - Salt is a randomly generated value that your code/system generates for each user and it is random without it ever being exposed to any UI or backend system.第 2 列 - Salt 是您的代码/系统为每个用户生成的随机生成值,它是随机的,不会暴露给任何 UI 或后端系统。 (I'll explain the use below) (我会在下面解释使用)

Column 1 - Will be the HASHED value of the user's password + (concatenate) salt.第 1 列 - 将是用户密码的哈希值 +(连接)盐。

You can read more about hashing here Common Hashing Algorithms您可以在此处阅读有关哈希的更多信息Common Hashing Algorithms

How this whole thing works:整个事情是如何运作的:

Hashing: Hashing is a way to create a UNIQUE value for each string based on an algorithm.哈希:哈希是一种基于算法为每个字符串创建唯一值的方法。 The uniqueness varies based on the algorithm but unless you have a gazillion records, you should be fine.唯一性因算法而异,但除非您有大量记录,否则应该没问题。 Also, the HASH value of each string is unique.此外,每个字符串的 HASH 值都是唯一的。 Meaning the Hash of a string "test" will always be the same, lets say "123"意味着字符串“test”的 Hash 将始终相同,假设为“123”

Salt: Salt is just a random string that is added to each password. Salt: Salt 只是添加到每个密码的随机字符串。 This way the HASH value is calculated as user's PASSWORD + SALT.这样 HASH 值被计算为用户的密码 + SALT。 This ensures that even if multiple users use the same password, their Password Hash (HASH(Password+Salt)) will be unique.这样可以确保即使多个用户使用相同的密码,他们的密码 Hash(HASH(密码+Salt))也是唯一的。

Setting the password设置密码

  • When the user set's their password, they will provide a password.当用户设置他们的密码时,他们将提供一个密码。
  • Your code will randomly generate a "salt" value.您的代码将随机生成一个“盐”值。
  • A third variable PasswordAndSalt = password + salt will be created.将创建第三个变量 PasswordAndSalt = password + salt。
  • Then a fourth variable hashValue = HASH(PasswordAndSalt) will be generated.然后会生成第四个变量 hashValue = HASH(PasswordAndSalt)。
  • You would then save the hashValue in Password Hash (column 1) and Salt in Salt (column 2).然后,您可以将 hashValue 保存在密码 Hash(第 1 列)中,将 Salt 保存在 Salt(第 2 列)中。

Adding SALT is a counter measure so if two users use the same password, the HASH value will still be different.添加 SALT 是一种反制措施,因此如果两个用户使用相同的密码,HASH 的值仍然会不同。

Validating User When the user enters their username and password, this is how your code will execute.验证用户当用户输入他们的用户名和密码时,这就是您的代码将如何执行。

Check if the username exists.检查用户名是否存在。

  • If the username exists, get its SALT value.如果用户名存在,获取其 SALT 值。
  • Take the password user provided and concatenate the SALT value you got from DB.获取用户提供的密码并连接您从数据库获得的 SALT 值。
  • Calculate HASH value for password + SALT计算密码 + SALT 的 HASH 值
  • If the calcualted HASH value matches the SALT value in your DB, authenticate the user.如果计算出的 HASH 值与数据库中的 SALT 值匹配,则对用户进行身份验证。
  • Else, tell the user authentication failed.否则,告诉用户认证失败。

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

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