【问题标题】:How would one securely store passwords in a way they're are still readable by an app?如何以一种应用程序仍可读取的方式安全地存储密码?
【发布时间】:2014-01-28 00:32:41
【问题描述】:

我有一个应用程序,它使用该网站的用户凭据从另一个网站提取信息。问题是,为了让它工作,我的应用程序必须知道用户的实际用户名/密码。

我正在尝试想出一些方法来安全地存储他们的密码,始终加密,但我的应用程序需要能够读取它们。它们将存储在 MySQL 数据库中。

我主要关心的是要有足够安全的东西,如果数据库以某种方式受到损害,黑客将无法读取/解码用户/密码信息。

我正在搜索公司如何存储信用卡信息,我会从那里开始,但我找不到足够清楚的解释..

它是如何完成的?我该怎么做?

谢谢。

【问题讨论】:

  • 使用散列。 md5() 内置在 php 中,因此将 md5 存储在数据库中,然后将登录尝试的 md5 与该 md5 进行比较
  • @RedAlert ,我的用户应该在我的应用程序上“保存”一次密码。所以不会有密码可以与 MD5 哈希值进行比较,因为他们不会多次登录。在他们保存密码后,我的应用必须能够从数据库中读取它们,但是我正在寻找某种方法来保护密码,而不是将它们以纯文本形式保存在数据库中。
  • 我建议使用比md5更强大的东西
  • 基于@RedAlert 的建议,我推荐reading this
  • 我认为密码散列不起作用,因为用户不会每次都输入密码,因此不会有任何密码可比较。 (这是一种方式)。

标签: php mysql encryption passwords password-encryption


【解决方案1】:

您不能使用哈希,因为它是一种方式。也许加密(AES,也许??)是您正在寻找的。它们在写入 mysql 之前会被加密。

【讨论】:

    【解决方案2】:

    您要做的是在将密码存储在数据库中时对密码进行哈希处理。当用户尝试登录时,您的应用程序将对他们提供的密码进行哈希处理,然后检查数据库中是否存在匹配的用户名/哈希密码对。

    我建议定义一个函数,让您以一致的方式散列密码:

    <?php
    
    function hashPWD($in) {
      $out = $in;
      for($i = 0; $i < 1000; $i++) {
        $out = hash('sha256', $out);
      }
      return $out;
    }
    

    另一个想法,既然你提到了一个应用程序,是在用户成功登录时生成某种会话标识符(基于凭据、时间戳和设备的任何识别信息)。在成功登录尝试时,您写入会话表,并且您的前端与后端进行的任何事务都会发送该会话标识符以及设备信息。

    【讨论】:

    • 虽然我同意散列密码是可行的方法,但我想说使用“自己的”散列函数并不是最佳做法。即使您将某个东西散列一千次,它仍然可能很容易受到攻击。请参阅this discussion at security.stackexchange.com。我建议使用知名库,例如PBKDF2
    • @DickW:这很公平;除此之外,如果提问者使用的是 PHP 5.5,则 this 似乎可用。
    • 是的,PHP 5.5 本身甚至有一个PBKDF2 implementation。很棒的东西。
    • (@DickW:如果您想编辑我的答案,请随意;我已将其标记为 CW)
    • 您没有阅读/完全理解这个问题。 OP 说他需要用户明文密码才能登录另一个服务。
    【解决方案3】:

    好吧,我想我有坏消息:

    如果您的应用必须知道用户的用户名和明文密码才能登录其他服务,否则没有其他方法,那么可能没有真正安全的解决方案。

    您可以将它们存储为明文,这显然很糟糕。 正面的:它显然很糟糕,而不是隐藏的糟糕。

    您可以加密它们并存储密文。但是:由于您必须在服务器上以某种方式提供密钥才能在您的服务需要明文时解密密文,所以这并不比明文好多少,因为可能有人入侵您的服务器也可以获得密码。

    如果您可以在特殊解决方案上投入一些精力,也许像 TPM 或加密智能卡这样的特殊加密硬件会有所帮助,因为这些东西是为安全密钥存储而设计的,因此闯入您的服务器的人可能无法读取钥匙。但是:就像您的应用程序使用该硬件解密内容一样,如果攻击者是您服务器上的 root 用户,他很可能会这样做。

    也就是说,您可以做的是使服务/服务器在所有其他方面(如通用系统、网络和网络安全、拥有良好的软件开发实践等)都尽可能安全。

    您还应该告诉您的用户,要为他们提供该功能,除了以某种不太安全的方式存储他们的密码之外别无他法。当然,他们需要在任何地方使用不同的密码。

    【讨论】:

      【解决方案4】:

      您需要创建 mysql_query 字符串,以便将输入的密码插入数据库。下面,我用一个函数来做到这一点。您必须将数据库中的用户表定义为“用户”,此代码才能正常工作。我使用哈希函数进行加密。

      $register_data = array(
      'password'  => $_POST['password']
      // Add other user stuff here, e.g. 'username' => $_POST['username']
      );
      function register_user($register_data) {
      array_walk($register_data, 'array_sanitize');
      $register_data['password'] = hash($register_data['password']);
      $fields = '`' . implode('`, `', array_keys($register_data)) . '`';
      $data = '\'' . implode('\', \'', $register_data) . '\'';
      mysql_query("INSERT INTO `users` ($fields) VALUES ($data)");
          }
      

      现在,进入密码表单。

      <form>
      <label>Enter your password!</label>
      <input type="type" name="password">
      

      注意输入是如何定义为密码的。 这应该适用于注册脚本。

      【讨论】:

      • 这行不通。密码是给外部网站的,不是他自己的,所以存储哈希是没用的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-31
      • 2013-09-03
      • 2012-06-14
      • 1970-01-01
      • 2015-07-13
      • 2019-04-01
      • 1970-01-01
      相关资源
      最近更新 更多