【问题标题】:Encrypt password and store in DB on android加密密码并存储在android上的数据库中
【发布时间】:2016-07-15 03:47:38
【问题描述】:

我已经为android制作了一个完整的工作注册/登录系统,一切都在空中和服务器端数据库中,问题是现在我的密码被直接保存到数据库中(没有加密),我已经搜索了大量的网站和 SoF 帖子和线程,但没有任何实际帮助我。

我阅读了 md5 和 sha1 、河豚和 bcrypt 的相关信息,但无法理解此类加密技术的正确实现方式。

连接是使用 php 请求建立的。注册码如下:

if($_SERVER['REQUEST_METHOD']=='POST'){
$username = $_POST['username'];
 $password = $_POST['password'];
 $email = $_POST['email'];
 $Firstname = $_POST['fname'];
 $Lastname = $_POST['lname'];
 $Date = $_POST['Date'];

 require_once('db_config.php');




    $check_username_email = "SELECT * FROM Users WHERE Username ='$username' AND Email = '$email'";

 $check_u_e = mysqli_fetch_array(mysqli_query($db,$check_username_email));

 $check_username = "SELECT * FROM Users WHERE Username ='$username'";

 $check_u = mysqli_fetch_array(mysqli_query($db,$check_username));

 $check_email = "SELECT * FROM Users WHERE Email ='$email'";

 $check_e = mysqli_fetch_array(mysqli_query($db,$check_email));

 if(isset($check_u_e)){

 echo 'Username AND Email already exist, please change them Both.';

 } 

 else if(isset($check_u)){

 echo 'Username already exists, please change it.';

 } 

 else if (isset($check_e)){

 echo 'Email already exists, please change it.';

 }  else{

 $sql = "INSERT INTO Users(Email,Username,Bio,Password,Fname,Lname,Regiser_Date) VALUES ('$email','$username',NULL,'$password','$Firstname','$Lastname','$Date')";

 if(mysqli_query($db,$sql)){

 echo "You have been successfully Registered";

 }   else{

 echo "Sorry, something went wrong - Try again.";

 }
 }
}else{

echo 'Server error - Please try again later.';
mysqli_close($db);
}

我的登录信息在这里:

    if($_SERVER['REQUEST_METHOD']=='POST'){
 $username = $_POST['username'];
 $password = $_POST['password'];

 require_once('db_config.php');


 $sql = "SELECT * FROM Users WHERE Username = '$username' AND Password = '$password'";

 $result = mysqli_query($db,$sql);

 $check = mysqli_fetch_array($result);

 if(isset($check)){
 echo 'Logged In';
 }
  else{
 echo 'Failed to login';
 }
 }

一切都很好,除了加密。有人可以指导我完成这个吗?我读到它需要 2 个面,一个来自客户端(android 应用程序),一个来自 php 服务器端

【问题讨论】:

  • 听起来您对cryptography terms 感到困惑。加密是双向的,加密哈希是单向的。调用 MD5 或 bcrypt 加密是错误的,并且可能是让您绊倒的部分原因。

标签: php android mysql encryption passwords


【解决方案1】:

要加密密码,您可以使用password_hash 函数。 在您的注册码中,在插入查询之前添加以下内容:

$options = [
'cost' => 12,
];
$password = password_hash($password, PASSWORD_BCRYPT, $options);

这将使用 BCRYPT 算法加密通过 POST 数组在注册时收到的密码。 BCRYPT 算法生成 60 个字符的哈希(将输入字符串切割为 70 个字符),因此,在您的数据库中,您需要有一个 CHAR(60) 密码字段来存储哈希密码。

您也可以在 $options 中添加自己的盐,如 php 文档中所述

强烈建议您不要为此函数生成自己的盐。如果您不指定,它将自动为您创建一个安全的盐。 如上所述,在 PHP 7.0 中提供 salt 选项将生成弃用警告。在未来的 PHP 版本中可能会移除对手动提供盐的支持。

现在您在数据库中拥有加密密码,在登录脚本中,您需要从数据库中检索散列密码,然后使用 password_verify() 函数将其与输入的密码进行比较:

$sql = "SELECT password FROM Users WHERE Username = '$username'";
$result = mysqli_query($db,$sql);
if(!$row = mysqli_fetch_assoc($result)){
echo "failed to login(invalid username)";
die();
//login failed->add code to redirect to login page
}
if(password_verify($password, $row['password'])){
//password match the stored hash
echo "logged in";
//sucessfully logged->retrive all additional data you need, save session, redirect to homepage etc...
}
else echo "failed to log in(invalid password)";

您将找到有关 password_hash() 和 password_verify() here 的所有信息,但请注意:

  1. 当通过 POST 数组发送到服务器时,密码在登录和注册时仍然容易受到攻击。出于这个原因,您应该安装一个证书,以便使用 HTTPS 协议来加密从服务器流向客户端的数据,反之亦然(查看here for configure ssl under apache)
  2. 您没有对输入采取任何预防措施,因此您的代码容易受到injections 的攻击。当您有未交易的数据时,我建议使用mysqliPDO 准备好的语句来查询数据库。

【讨论】:

  • 我现在尝试实现这一点,密码部分和验证正在工作,但它总是给出无效的用户名 - 它总是打印“登录”回声。 @塞巴斯蒂亚诺
  • 我在登录代码中忘记了非运算符,对此感到抱歉。现在应该没问题了
  • 非常感谢,效果很好!从早上开始就一直在寻找一种方法来匹配它们。你能告诉我我是否能更多地证明这种安全性吗? (你提到)我应该使用 mysqli,我已经在使用 mysqli。还有appache下的ssl,还有什么我可以添加的吗? @塞巴斯蒂亚诺
  • 我对 ssl 了解不多(但我只是一名学生),而且我从未实施过它,因为证书不像我所知的那样免费。顺便说一句,您可以添加准备好的语句(您正在使用 mysqli 但不使用准备好的语句),这将阻止几乎所有的注入攻击。检查this 使用mysqli 准备语句的教程,这是一个简单的概念:)
  • 伟大的概念,已经实现!简单而有效,我什至没有在我喜欢的查询中引入变量!
【解决方案2】:

所以它会像这样,在数据库中存储密码时,使用任何散列或加密,如 bcrypt、md5、sha1 并将其存储在数据库中。 当用户想要登录时,再次使用相同的散列或加密机制将存储在 DB 中的值与 user 传递的值进行比较。 如果是,则登录成功。

现在,

您对插入的查询将更改类似的内容,

 $sql = "INSERT INTO Users(Email,Username,Bio,Password,Fname,Lname,Regiser_Date) VALUES ('$email','$username',NULL,'md5($password)','$Firstname','$Lastname','$Date')";

还有

$sql = "SELECT * FROM Users WHERE Username = '$username' AND Password = 'md5($password)'";

然后使用 Bcrypt,

一个例子显示在

$options = [
    'cost' => 12,
];
echo password_hash("password", PASSWORD_BCRYPT, $options)."\n";

http://php.net/manual/en/function.password-hash.php

【讨论】:

  • 我已经试过了,但是 md5 太弱了,我想要一个更好的加密方法。你有什么想法吗?
  • password_hash 是一个正确的选项,它从未与“md5”和“sha1”有任何关系
  • 我还阅读了有关 bcrypy 的信息,我的问题是:如何将用户输入的密码与数据库中的密码(已经加密)匹配?我成功加密了密码并存储在数据库中,但是如何验证它们才能登录@Naruto
猜你喜欢
  • 2020-03-20
  • 2012-04-07
  • 2011-12-20
  • 2011-04-26
  • 2019-03-17
  • 1970-01-01
  • 1970-01-01
  • 2011-07-15
  • 2011-04-28
相关资源
最近更新 更多