23

可能是一个非常新手的问题,但是,我一直在阅读并发现在理解密码的创建和存储方面有些困难。从我读过的内容来看,md5/hash 密码是将它们存储在数据库中的最佳方式。但是,我将如何首先创建这些密码?

所以说我有一个用户 bob 和密码 bob123 的登录页面 - 我将如何 1. 将 bobs 密码输入数据库以开始(散列) 2. 我如何检索并确认散列密码?

谢谢

4

9 回答 9

44

编辑 2017/11/09:一定要看看 O Jones 的答案。

首先,MD5 不是您可以用于此尝试的最佳散列方法 sha256 或 sha512

也就是说,让我们使用hash('sha256')而不是md5()表示过程的散列部分。

当您第一次创建用户名和密码时,您将使用一些盐(一些随机的额外字符添加到每个密码以使其更长/更强)对原始密码进行哈希处理。

可能看起来像这样来自创建用户表单:

$escapedName = mysql_real_escape_string($_POST['name']); # use whatever escaping function your db requires this is very important.
$escapedPW = mysql_real_escape_string($_POST['password']);

# generate a random salt to use for this account
$salt = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));

$saltedPW =  $escapedPW . $salt;

$hashedPW = hash('sha256', $saltedPW);

$query = "insert into user (name, password, salt) values ('$escapedName', '$hashedPW', '$salt'); ";

然后在登录时它看起来像这样:

$escapedName = mysql_real_escape_string($_POST['name']);
$escapedPW = mysql_real_escape_string($_POST['password']);

$saltQuery = "select salt from user where name = '$escapedName';";
$result = mysql_query($saltQuery);
# you'll want some error handling in production code :)
# see http://php.net/manual/en/function.mysql-query.php Example #2 for the general error handling template
$row = mysql_fetch_assoc($result);
$salt = $row['salt'];

$saltedPW =  $escapedPW . $salt;

$hashedPW = hash('sha256', $saltedPW);

$query = "select * from user where name = '$escapedName' and password = '$hashedPW'; ";

# if nonzero query return then successful login
于 2011-07-21T20:16:37.720 回答
9

您必须根据密码进行推理:

md5('bob123');在 bob 注册到您的应用程序时存储密码

$query = "INSERT INTO users (username,password) VALUES('bob','".md5('bob123')."');

然后,当鲍勃登录时:

$query = "SELECT * FROM users WHERE username = 'bob' AND password = '".md5('bob123')."';

显然使用变量作为用户名和密码,这些查询是由 php 生成的,然后你可以在 mysql 上执行它们

于 2011-07-21T19:57:24.873 回答
8

请不要使用 MD5 进行密码散列。这样的密码可以在几毫秒内被破解。你肯定会被网络犯罪分子攻击。

PHP 提供基于可靠随机盐和多轮 Rijndael / AES 加密的高质量且面向未来的密码哈希子系统。

当用户首次提供密码时,您可以像这样散列它:

 $pass = 'whatever the user typed in';
 $hashed_password = password_hash( "secret pass phrase", PASSWORD_DEFAULT );

然后,存储在 MySQL$hashed_password的列中。varchar(255)稍后,当用户想要登录时,您可以从 MySQL 中检索散列密码并将其与用户提供的登录密码进行比较。

 $pass = 'whatever the user typed in';
 $hashed_password = 'what you retrieved from MySQL for this user';
 if ( password_verify ( $pass , $hashed_password )) {
    /* future proof the password */
    if ( password_needs_rehash($hashed_password , PASSWORD_DEFAULT)) {
       /* recreate the hash */
       $rehashed_password = password_hash($pass, PASSWORD_DEFAULT );
       /* store the rehashed password in MySQL */
     }
     /* password verified, let the user in */
 }
 else {
     /* password not verified, tell the intruder to get lost */
 }

这种面向未来的工作如何运作?未来的 PHP 版本将适应匹配更快、更容易破解的加密。如果需要重新散列密码以使其更难破解,该 password_needs_rehash()功能的未来实现将检测到这一点。

不要重新发明瘪胎。使用经过专业设计和审查的开源代码来确保安全。

于 2015-10-10T14:18:27.293 回答
6

插入:

INSERT INTO ... VALUES ('bob', MD5('bobspassword'));

恢复:

SELECT ... FROM ... WHERE ... AND password=md5('hopefullybobspassword');

是您如何直接在查询中执行此操作。但是,如果您的 MySQL 启用了查询日志记录,那么密码的明文将被写入此日志。所以......你想在你的脚本中进行 MD5 转换,然后将生成的哈希插入到查询中。

于 2011-07-21T20:00:06.873 回答
3

PHP 有一个叫做 md5 的方法 ;-) Just $password = md5($passToEncrypt);

如果您在 SQL 中搜索,您也可以使用 MySQL 方法 MD5()....

 SELECT * FROM user WHERE Password='. md5($password) .'

或 SELECT * FROM ser WHERE Password=MD5('.$password .')

要插入它,你可以这样做。

于 2011-07-21T19:59:18.760 回答
3

为什么不使用 MySQL 内置的密码哈希:

http://dev.mysql.com/doc/refman/5.1/en/password-hashing.html

mysql> SELECT PASSWORD('mypass');
+-------------------------------------------+
| PASSWORD('mypass')                        |
+-------------------------------------------+
| *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 |
+-------------------------------------------+

为了比较,你可以这样:

select id from PassworTable where Userid='<userid>' and Password=PASSWORD('<password>')

如果它返回一个值,那么用户是正确的。

于 2011-07-21T20:04:40.493 回答
2

我在 PHP 方面并不出色,但我认为这就是你所做的:

$password = md5($password)

并且$password将是$_POST['password']或其他

于 2011-07-21T19:57:59.863 回答
0

只需通过以下行获取哈希并将其存储到数据库中:

$encryptedValue = md5("YOUR STRING");
于 2015-10-10T13:49:11.200 回答
0

为了进一步提高安全性,您可以使用 md5 加密以及两个不同的盐字符串,一个在 php 文件中定义的静态盐,然后一个为每个密码记录随机生成的唯一盐。

以下是生成盐、md5 字符串和存储的方法:

    $unique_salt_string = hash('md5', microtime()); 
    $password = hash('md5', $_POST['password'].'static_salt'.$unique_salt_string);
    $query = "INSERT INTO users (username,password,salt) VALUES('bob','".$password."', '".$unique_salt_string."');

现在您有了一个静态盐,它对您的所有密码都有效,它存储在 .php 文件中。然后,在注册执行时,您为该特定密码生成一个唯一的哈希。

这一切都结束了:两个拼写完全相同的密码,将有两个不同的哈希值。唯一的哈希值与当前 ID 一起存储在数据库中。如果有人抓取数据库,他们将拥有每个特定密码的每个唯一盐。但是他们没有的是你的静态盐,这让每个“黑客”的事情变得更加困难。

这是您在 login.php 上检查密码有效性的方法,例如:

     $user = //username input;
     $db_query = mysql_query("SELECT salt FROM users WHERE username='$user'");
     while($salt = mysql_fetch_array($db_query)) {
            $password = hash('md5',$_POST['userpassword'].'static_salt'.$salt[salt]);
}

这种方法非常强大和安全。如果要使用 sha512 加密,只需将其放在哈希函数中,而不是上面代码中的 md5 即可。

于 2017-05-19T11:33:13.040 回答