0

我想知道如何编辑我的代码以加密用户密码。目前,用户填写一个 HTML 表单,该表单customerRegister.php在提交查询之前要经过一系列验证。

客户注册.php

registerUser($_POST['firstName'], $_POST['lastName'], $_POST['username'], $_POST['houseNo'], $_POST['StreetName'], $_POST['town'], $_POST['postCode'], $_POST['emailAddress'], $_POST['phoneNumber'], $_POST['password'], $_POST['conPassword'],$_POST['carRegistration'],$_POST['carMake'],$_POST['carModel'],$_POST['carYear'],$_POST['carEngineSize'],$_POST['carFuel']);

 function registerUser($firstName, $lastName, $username, $houseNo, $streetName, $town, $postCode, $emailAddress, $phoneNumber, $password, $conPassword, $registration, $carMake, $carModel, $carYear, $carEngineSize, $carFuel) {

      $registerQuery = new UserLoginQueries();

/********************************
SERIES OF VALIDATIONS
********************************/

$registerQuery->insertUser($firstName, $lastName, $username, $houseNo, $streetName, $town, $postCode, $emailAddress, $phoneNumber, $password);

然后将这些详细信息传递给执行查询的 userLoginQueries.php。

用户登录查询.php

  public function insertUser($custFirstName, $custLastName, $username, $houseNo, $streetName, $town, $postCode, $email, $number, $pass) {
    $sth = $this->conn->prepare("INSERT INTO `customer`(`CustFirstName`, `CustLastName`, `HouseNo`, `StreetName`, `Town`, `PostCode`, `EmailAddress`, `PhoneNumber`, `Username`, `Password`) VALUES (?,?,?,?,?,?,?,?,?,?)");
    $sth->bindValue (1, $custFirstName);
    $sth->bindValue (2, $custLastName);
    $sth->bindValue (3, $houseNo);
    $sth->bindValue (4, $streetName);
    $sth->bindValue (5, $town);
    $sth->bindValue (6, $postCode);
    $sth->bindValue (7, $email);
    $sth->bindValue (8, $number);
    $sth->bindValue (9, $username);
    $sth->bindValue (10, $pass);
    $sth->execute(); 
  }

当用户输入他们的登录信息时,将运行以下查询:

  public function queryLogin($username, $password) {
    $sth = $this->conn->prepare("SELECT * FROM customer WHERE Username = ? AND Password = ? AND UserType = 'Customer'");
    $sth->bindValue (1, $username);
    $sth->bindValue (2, $password);
    $sth->execute();
    $count = $sth->rowCount();
    return $count;
    }

如何修改我的代码以加密用户密码?

4

3 回答 3

2

您应该使用盐使用散列算法http://en.wikipedia.org/wiki/Hash_function(单向算法)存储您的密码,请参阅http://en.wikipedia.org/wiki/Salt_(cryptography)

造成这种情况的根本原因之一是,如果您的数据库遭到破坏,攻击者将不知道实际密码是什么。

一个简单的散列算法,是 sha-1。您可以在此处查看如何使用它http://php.net/manual/en/function.sha1.php

使用盐散列

以下可能会有所帮助: -

$sth->bindValue (2, sha1($password . "random private stuff here as salt"));

下次要验证密码时,只需将输入的密码和盐与实际值和盐进行比较即可。这将让您知道密码是否正确,而无需以明文形式保存用户密码。

为什么要用盐?

好吧,虽然通常一种方式的功能不能被逆转,但它们可以被蛮力强迫。这可能意味着即使您使用的是散列算法,某些密码也可能容易受到攻击。

于 2013-04-22T18:27:45.823 回答
2

请看一下这个答案:How do you use bcrypt for hashing passwords in PHP? ,您只需$hash = $bcrypt->hash('password'); 在注册用户时调用 ,然后将密码的散列版本保存到数据库中。然后,您可以使用验证用户$isGood = $bcrypt->verify('password', $hash);

于 2013-04-22T18:27:49.263 回答
2

这里要记住的重要一点是“加密”是错误的词。加密的能力意味着解密的能力,这对密码来说是一件坏事。你永远不应该解密密码。相反,您需要散列密码。散列使​​用复杂的数学问题将文本输入(例如密码)提炼成一个很长的数字。潜在数字越长,哈希可能越安全。这里重要的是哈希不能被反转。如果我的密码是“p4$$w0rd”,而生成的哈希是“12345”,则永远无法从“12345”中获取“p4$$w0rd”。为了对用户进行身份验证,当有人尝试登录时,您计算他们使用的密码的哈希值,然后将其与您存储的哈希值进行比较。您不会将密码存储在任何地方。曾经。是的,这确实意味着您永远不会为用户提供找回丢失密码的选项;你只允许他们重置它。

此外,哈希本身还不够好。事实证明,密码数据库本身一直受到威胁,黑客通常已经知道你的哈希值。黑客投入了大量资源来创建现成的密码输入表,这些表将产生给定的哈希值。因此,对于我的示例五“数字”哈希,他们将为从“00001”到“99999”的每个可能的哈希预先计算一些东西。它们的“12345”值可能与我的“p4$$w0rd”不匹配,但没关系:如果它产生相同的哈希值,那就足够了。黑客可以使用它来查看受感染的数据库并为每个用户发现一组有效的凭据。为此,还需要加盐您的密码在散列之前。当您对密码进行加盐时,您会在散列之前修改提交的字符串。在验证我的示例密码时,您将首先附加我的用户帐户的盐,而不是检查“p4$$w0rd”,然后对结果进行哈希处理。如果破解者知道我的散列并且能够在表中查找会产生我的散列的输入,那么这对他不再有帮助,因为您将以一种会破坏所有预先计算的散列结果的方式修改他的输入。这让他重新暴力猜测每一个密码。

同样重要的是要知道并非所有的散列算法都是平等的。一些散列算法,例如 md5,是专门为快速而创建的,因此您可以使用它们快速将较大的文本块与已知样本进行比较。这些算法非常不适合用于密码,因为黑客可以很快猜出许多可能的密码。您需要一个非常的散列算法,因此即使使用超快速或专用硬件,黑客也需要很长时间(可能是几个世纪)才能猜出真正的密码。最好的算法可以动态调整,随着时间的推移,硬件变得越来越快,算法变得越来越慢。这些算法的示例是“bcrypt”和“scrypt”。

最后,最重要的教训是根本不要尝试构建自己的身份验证系统。身份验证的问题在于,很容易构建一些看似有效的东西,但仍然存在一些微妙的缺陷,比如一年后你可能会发现六个月前你被黑客入侵了。该系统甚至可以通过许多编写良好的单元测试,但仍然存在这些细微的缺陷。您总是希望尽可能多地依赖可用于您的平台的预先编写的身份验证模块。这也是允许您通过 Facebook、Twitter、OpenID 等登录的身份验证方案变得越来越流行的原因。

于 2013-04-22T18:40:05.593 回答