密码验证;这样做是否安全?

时间:2021-08-11 18:03:09

I have a classifieds website, where everybody may put ads of their products.

我有一个分类广告网站,每个人都可以放置他们产品的广告。

For each classified, the user has to enter a password (so that they can delete the classified whenever they wish).

对于每个分类,用户必须输入密码(以便他们可以随时删除分类)。

So basically, when somebody wants to delete a classified, they click on the classified, click on the delete button, and enter the pass.

所以基本上,当有人想要删除分类时,他们点击分类,点击删除按钮,然后输入通行证。

I use MySql as a database.

我使用MySql作为数据库。

I use this code basically:

我基本上使用这个代码:

if ($pass==$row['poster_password'])

where row[poster_password] is fetched from MySql...

从MySql获取行[poster_password] ...

What do you think? Thanks

你怎么看?谢谢

8 个解决方案

#1


9  

See this: Secure hash and salt for PHP passwords

请参阅:PHP密码的安全散列和salt

Hash their password (maybe with some salt) on the way into the database. Store their hashed password in the database (NOT their actual password). Then fetch their hashed password from the database and hash their input password and compare the hashed passwords.

在进入数据库的路上哈希密码(可能带有一些盐)。将散列密码存储在数据库中(而不是实际密码)。然后从数据库中获取散列密码并散列输入密码并比较散列密码。

Some lame pseudo code:

一些蹩脚的伪代码:

password_hash = hash(password_cleartext)
# store password_hash in database

Later:

input_password_hash = hash(input_password_cleartext)
fetched_password_hash_from_db = fetch(db, password_hash)
if (input_password_hash == fetched_password_hash_from_db) {
    ... authenticated ...
}

For a start with php, try: http://php.net/manual/en/function.sha1.php

首先使用php,请尝试:http://php.net/manual/en/function.sha1.php

#2


4  

Your code looks safe, but your design may need some work.

您的代码看起来很安全,但您的设计可能需要一些工作。

SQL Injection

The dangerous part of the code is in storing anything in the database, or showing anything to the users, that is collected from the user. So, the part you have to be careful with occurs prior to your example. Ensure that you're validating, filtering, and escaping any data that you collect from the user, including the password and the ad information.

代码的危险部分是将任何内容存储在数据库中,或者向用户显示从用户收集的任何内容。因此,您需要注意的部分发生在您的示例之前。确保您正在验证,过滤和转义从用户收集的任何数据,包括密码和广告信息。

Encryption

The advantage of storing the password in the database is that you can let the user retrieve the password via email or some other means if they lose it.

将密码存储在数据库中的优点是,如果用户丢失密码,您可以通过电子邮件或其他方式让用户检索密码。

However, if you do store passwords, you should store them encrypted, using a secret key, so that if someone is able to direct read access to your database, they can't read all the passwords in plain text. Still, you're going to have to store the secret key somewhere, and if someone gets your secret key and has access to your database, they will have access to all of the passwords.

但是,如果您确实存储了密码,则应使用密钥对它们进行加密存储,这样,如果有人能够直接读取您对数据库的读取权限,则无法以纯文本格式读取所有密码。但是,您必须将密钥存储在某处,如果有人获取了您的密钥并且可以访问您的数据库,他们将可以访问所有密码。

Hash Values (recommended)

哈希值(推荐)

It's best practice and more secure to only store one way hash values (SHA1 or SHA256) of the passwords in the database instead of the actual passwords. This way, you cannot retrieve the password. Hash values are intentionally one way by throwing away some of the data.

最好的做法是更安全,只能在数据库中存储密码的单向哈希值(SHA1或SHA256)而不是实际密码。这样,您无法检索密码。通过丢弃一些数据,哈希值是有意的一种方式。

Instead of retrieving the original password, you hash the password that the user enters and compare the hash value against the stored hash value to see if it matches. If the user loses the password in this case, instead of emailing the password to the user, you email the user a new, randomly generated password.

您可以散列用户输入的密码,并将散列值与存储的散列值进行比较,以查看是否匹配,而不是检索原始密码。如果用户在这种情况下丢失密码,则不会通过电子邮件将密码发送给用户,而是通过电子邮件向用户发送新的随机生成的密码。

Storing only the hash value protects your data even further, since even if the user has read access to your database, the hash values offer no advantage, and there is no secret key that will unlock all of your hash values.

仅存储哈希值可以进一步保护您的数据,因为即使用户具有对数据库的读访问权限,哈希值也没有优势,并且没有密钥可以解锁所有哈希值。

When you hash the passwords, be sure to use a random salt value and store the salt to protect your list of hashes against rainbow attacks.

当您对密码进行哈希处理时,请确保使用随机盐值并存储盐以保护您的哈希列表免受彩虹攻击。

Summary

Sometimes you don't get to choose the password. Sometimes the password comes from another system, so you don't always have a choice, and sometimes your superiors (maybe even the users) will demand that they be able to retrieve passwords, however, when possible, you should choose the more secure option.

有时您无法选择密码。有时密码来自另一个系统,因此您并不总是有选择权,有时您的上司(甚至可能是用户)会要求他们能够检索密码,但是,如果可能,您应该选择更安全的选项。

Note that all of this encryption and hash value business only partially protects your server against people who are able to obtain read only access to your data. Sometimes, getting your data is enough of a prize, so if the user can read the password hash, can they read your credit card numbers?

请注意,所有此加密和哈希值业务仅部分保护您的服务器免受能够获取对您的数据的只读访问权限的人的影响。有时候,获取数据就足够了,所以如果用户可以读取密码哈希值,他们是否可以读取您的信用卡号码?

You need to protect your database. Do you have a secure password on your database system? Do you only allow local access to your data? Have you created a database user with least privileges to use in your application? Are you properly protecting yourself from SQL injection and scripting attacks?

您需要保护您的数据库。您的数据库系统上是否有安全密码?您是否只允许本地访问您的数据?您是否创建了一个在应用程序中使用最少权限的数据库用户?您是否正确保护自己免受SQL注入和脚本攻击?

If someone has read and write access to your data, the whole password business becomes moot.

如果有人对您的数据具有读写权限,那么整个密码业务就没有实际意义了。

#3


2  

Don't store the actual password in the database. Instead store a checksum (MD5, SHA1, etc). When you want to compare, perform a checksum of the value the user submits and compare the checksums.

不要将实际密码存储在数据库中。而是存储校验和(MD5,SHA1等)。如果要进行比较,请执行用户提交的值的校验和,并比较校验和。

That way you never have the actual password in memory.

这样你就不会在内存中拥有实际的密码。

#4


1  

Best practice is to keep a salted sha1 hash in the database:

最佳做法是在数据库中保留salted sha1哈希:

if (sha1($pass.$row['poster_salt'])==$row['poster_password'])

(poster_salt is a random string generated and saved when the user chooses the password.)

(poster_salt是在用户选择密码时生成并保存的随机字符串。)

That way if an attacker gets access to your database, they still won't get the passwords of the users (which are probably used elsewhere too - most people don't bother to choose different passwords for different sites).

这样,如果攻击者可以访问您的数据库,他们仍然无法获取用户的密码(也可能在其他地方也使用过 - 大多数人都懒得为不同的站点选择不同的密码)。

Also, you should use secure (HTTPS) connection. And require sufficiently strong passwords.

此外,您应该使用安全(HTTPS)连接。并要求足够强大的密码。

(At least if you want good security, which might be an overkill in the case of a simple ad listing).

(至少如果你想要一个好的安全性,在一个简单的广告列表的情况下这可能是一种过度杀伤力)。

#5


0  

I would encrypt the password before storing it, then decrypt when retrieving it so you can check it against what the user entered in plaintext (per your example code above).

我会在存储密码之前对其进行加密,然后在检索密码时进行解密,这样您就可以根据用户输入的明文进行检查(根据上面的示例代码)。

Also, protect yourself against any SQL injections, or someone could see all the passwords (and other data) in your database.

此外,保护自己免受任何SQL注入,或者有人可以看到数据库中的所有密码(和其他数据)。

#6


0  

This implies the passwords are placed into your passwords unencrypted. If this is the case you should be using some sort of encryption when entering the passwords. One way of doing this is the MD5 function which hashes the password.

这意味着密码将以未加密的方式放入您的密码中。如果是这种情况,则在输入密码时应使用某种加密方式。执行此操作的一种方法是使用哈希密码的MD5功能。

When doing the insert you would do

在进行插入时,您可以这样做

Insert into table(email, password, whatever) values('$email', md5($password), whatever)

And when comparing you would do

比较你会做的

if (md5($pass) == $row['password'])

#7


0  

You should hash the password somehow and store and compare using the hashed version. See this link for more details:

您应该以某种方式散列密码并使用散列版本进行存储和比较。有关详细信息,请参阅此链接:

http://phpsec.org/articles/2005/password-hashing.html

#8


0  

my suggestion is the following

我的建议如下

the users table have two columns, one called "password" and the other "salt"

users表有两列,一列叫“密码”,另一列叫“盐”

$password =  'youruserpassword in plain text';
$salt = bin2hex(openssl_random_pseudo_bytes(32));
$passtostore = hash_hmac('sha384', $password, $salt);
insert into users(password, salt) values($passtostore, $salt);

Then to verify if the user has entered the correct password...

然后验证用户是否输入了正确的密码......

retrive both password and salt from the database and

从数据库中检索密码和salt

if(hash_hmac('sha384',$userpass, $row['salt']) === $row['password']) { 
 // is valid 
 }

#1


9  

See this: Secure hash and salt for PHP passwords

请参阅:PHP密码的安全散列和salt

Hash their password (maybe with some salt) on the way into the database. Store their hashed password in the database (NOT their actual password). Then fetch their hashed password from the database and hash their input password and compare the hashed passwords.

在进入数据库的路上哈希密码(可能带有一些盐)。将散列密码存储在数据库中(而不是实际密码)。然后从数据库中获取散列密码并散列输入密码并比较散列密码。

Some lame pseudo code:

一些蹩脚的伪代码:

password_hash = hash(password_cleartext)
# store password_hash in database

Later:

input_password_hash = hash(input_password_cleartext)
fetched_password_hash_from_db = fetch(db, password_hash)
if (input_password_hash == fetched_password_hash_from_db) {
    ... authenticated ...
}

For a start with php, try: http://php.net/manual/en/function.sha1.php

首先使用php,请尝试:http://php.net/manual/en/function.sha1.php

#2


4  

Your code looks safe, but your design may need some work.

您的代码看起来很安全,但您的设计可能需要一些工作。

SQL Injection

The dangerous part of the code is in storing anything in the database, or showing anything to the users, that is collected from the user. So, the part you have to be careful with occurs prior to your example. Ensure that you're validating, filtering, and escaping any data that you collect from the user, including the password and the ad information.

代码的危险部分是将任何内容存储在数据库中,或者向用户显示从用户收集的任何内容。因此,您需要注意的部分发生在您的示例之前。确保您正在验证,过滤和转义从用户收集的任何数据,包括密码和广告信息。

Encryption

The advantage of storing the password in the database is that you can let the user retrieve the password via email or some other means if they lose it.

将密码存储在数据库中的优点是,如果用户丢失密码,您可以通过电子邮件或其他方式让用户检索密码。

However, if you do store passwords, you should store them encrypted, using a secret key, so that if someone is able to direct read access to your database, they can't read all the passwords in plain text. Still, you're going to have to store the secret key somewhere, and if someone gets your secret key and has access to your database, they will have access to all of the passwords.

但是,如果您确实存储了密码,则应使用密钥对它们进行加密存储,这样,如果有人能够直接读取您对数据库的读取权限,则无法以纯文本格式读取所有密码。但是,您必须将密钥存储在某处,如果有人获取了您的密钥并且可以访问您的数据库,他们将可以访问所有密码。

Hash Values (recommended)

哈希值(推荐)

It's best practice and more secure to only store one way hash values (SHA1 or SHA256) of the passwords in the database instead of the actual passwords. This way, you cannot retrieve the password. Hash values are intentionally one way by throwing away some of the data.

最好的做法是更安全,只能在数据库中存储密码的单向哈希值(SHA1或SHA256)而不是实际密码。这样,您无法检索密码。通过丢弃一些数据,哈希值是有意的一种方式。

Instead of retrieving the original password, you hash the password that the user enters and compare the hash value against the stored hash value to see if it matches. If the user loses the password in this case, instead of emailing the password to the user, you email the user a new, randomly generated password.

您可以散列用户输入的密码,并将散列值与存储的散列值进行比较,以查看是否匹配,而不是检索原始密码。如果用户在这种情况下丢失密码,则不会通过电子邮件将密码发送给用户,而是通过电子邮件向用户发送新的随机生成的密码。

Storing only the hash value protects your data even further, since even if the user has read access to your database, the hash values offer no advantage, and there is no secret key that will unlock all of your hash values.

仅存储哈希值可以进一步保护您的数据,因为即使用户具有对数据库的读访问权限,哈希值也没有优势,并且没有密钥可以解锁所有哈希值。

When you hash the passwords, be sure to use a random salt value and store the salt to protect your list of hashes against rainbow attacks.

当您对密码进行哈希处理时,请确保使用随机盐值并存储盐以保护您的哈希列表免受彩虹攻击。

Summary

Sometimes you don't get to choose the password. Sometimes the password comes from another system, so you don't always have a choice, and sometimes your superiors (maybe even the users) will demand that they be able to retrieve passwords, however, when possible, you should choose the more secure option.

有时您无法选择密码。有时密码来自另一个系统,因此您并不总是有选择权,有时您的上司(甚至可能是用户)会要求他们能够检索密码,但是,如果可能,您应该选择更安全的选项。

Note that all of this encryption and hash value business only partially protects your server against people who are able to obtain read only access to your data. Sometimes, getting your data is enough of a prize, so if the user can read the password hash, can they read your credit card numbers?

请注意,所有此加密和哈希值业务仅部分保护您的服务器免受能够获取对您的数据的只读访问权限的人的影响。有时候,获取数据就足够了,所以如果用户可以读取密码哈希值,他们是否可以读取您的信用卡号码?

You need to protect your database. Do you have a secure password on your database system? Do you only allow local access to your data? Have you created a database user with least privileges to use in your application? Are you properly protecting yourself from SQL injection and scripting attacks?

您需要保护您的数据库。您的数据库系统上是否有安全密码?您是否只允许本地访问您的数据?您是否创建了一个在应用程序中使用最少权限的数据库用户?您是否正确保护自己免受SQL注入和脚本攻击?

If someone has read and write access to your data, the whole password business becomes moot.

如果有人对您的数据具有读写权限,那么整个密码业务就没有实际意义了。

#3


2  

Don't store the actual password in the database. Instead store a checksum (MD5, SHA1, etc). When you want to compare, perform a checksum of the value the user submits and compare the checksums.

不要将实际密码存储在数据库中。而是存储校验和(MD5,SHA1等)。如果要进行比较,请执行用户提交的值的校验和,并比较校验和。

That way you never have the actual password in memory.

这样你就不会在内存中拥有实际的密码。

#4


1  

Best practice is to keep a salted sha1 hash in the database:

最佳做法是在数据库中保留salted sha1哈希:

if (sha1($pass.$row['poster_salt'])==$row['poster_password'])

(poster_salt is a random string generated and saved when the user chooses the password.)

(poster_salt是在用户选择密码时生成并保存的随机字符串。)

That way if an attacker gets access to your database, they still won't get the passwords of the users (which are probably used elsewhere too - most people don't bother to choose different passwords for different sites).

这样,如果攻击者可以访问您的数据库,他们仍然无法获取用户的密码(也可能在其他地方也使用过 - 大多数人都懒得为不同的站点选择不同的密码)。

Also, you should use secure (HTTPS) connection. And require sufficiently strong passwords.

此外,您应该使用安全(HTTPS)连接。并要求足够强大的密码。

(At least if you want good security, which might be an overkill in the case of a simple ad listing).

(至少如果你想要一个好的安全性,在一个简单的广告列表的情况下这可能是一种过度杀伤力)。

#5


0  

I would encrypt the password before storing it, then decrypt when retrieving it so you can check it against what the user entered in plaintext (per your example code above).

我会在存储密码之前对其进行加密,然后在检索密码时进行解密,这样您就可以根据用户输入的明文进行检查(根据上面的示例代码)。

Also, protect yourself against any SQL injections, or someone could see all the passwords (and other data) in your database.

此外,保护自己免受任何SQL注入,或者有人可以看到数据库中的所有密码(和其他数据)。

#6


0  

This implies the passwords are placed into your passwords unencrypted. If this is the case you should be using some sort of encryption when entering the passwords. One way of doing this is the MD5 function which hashes the password.

这意味着密码将以未加密的方式放入您的密码中。如果是这种情况,则在输入密码时应使用某种加密方式。执行此操作的一种方法是使用哈希密码的MD5功能。

When doing the insert you would do

在进行插入时,您可以这样做

Insert into table(email, password, whatever) values('$email', md5($password), whatever)

And when comparing you would do

比较你会做的

if (md5($pass) == $row['password'])

#7


0  

You should hash the password somehow and store and compare using the hashed version. See this link for more details:

您应该以某种方式散列密码并使用散列版本进行存储和比较。有关详细信息,请参阅此链接:

http://phpsec.org/articles/2005/password-hashing.html

#8


0  

my suggestion is the following

我的建议如下

the users table have two columns, one called "password" and the other "salt"

users表有两列,一列叫“密码”,另一列叫“盐”

$password =  'youruserpassword in plain text';
$salt = bin2hex(openssl_random_pseudo_bytes(32));
$passtostore = hash_hmac('sha384', $password, $salt);
insert into users(password, salt) values($passtostore, $salt);

Then to verify if the user has entered the correct password...

然后验证用户是否输入了正确的密码......

retrive both password and salt from the database and

从数据库中检索密码和salt

if(hash_hmac('sha384',$userpass, $row['salt']) === $row['password']) { 
 // is valid 
 }