【问题标题】:MySQL - how to encrypt passwordMySQL - 如何加密密码
【发布时间】:2013-04-15 18:20:07
【问题描述】:

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

customerRegister.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。

userLoginQueries.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;
    }

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

【问题讨论】:

  • 我已经检查了文档,但对我来说不是很清楚。
  • @Sparksis 不,这些函数应该只供 MySQL 用户使用!
  • 您可以在 php 中使用 md5 哈希并将其存储在您的数据库中。这取决于您是否需要解密密码。
  • @Gumbo 该功能是有限且可配置的,将其用于应用程序密码散列有什么问题。

标签: mysql sql authentication encryption


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您确实应该使用使用 salt 的散列算法 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"));
    

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

    为什么要使用盐?

    好吧,虽然通常单向函数不能反转,但它们可以被暴力破解。这可能意味着即使您使用的是散列算法,某些密码也可能容易受到攻击。

    【讨论】:

    【解决方案3】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-21
      • 2011-08-09
      • 2020-11-22
      • 2014-06-23
      • 1970-01-01
      • 1970-01-01
      • 2013-07-21
      • 2012-07-21
      相关资源
      最近更新 更多