【问题标题】:How to safely store a password inside PHP code?如何在 PHP 代码中安全地存储密码?
【发布时间】:2010-11-28 18:53:07
【问题描述】:

如何在 PHP 代码中设置密码并保证在浏览器中查看该页面的任何人都无法找回密码?

<?php $password = 'password' ?> 够了吗?有没有更好、更安全的方法?

【问题讨论】:

  • 也许您可以告诉我们,为什么要将密码存储在 php 文件中。这在答案中造成了很多混乱
  • 我正在为客户开发一个脚本。我正在使用“测试”帐户,因为客户不希望除他之外的任何人知道密码。我必须找到一种方法,让他可以在我不知情的情况下轻松地将密码从测试帐户更改为他的。顺便说一句,这不会与数据库交互。
  • 所以您将帐户信息存储在 php 文件中?如果是这样,那么公认的答案到目前为止还不是最好的。在这种情况下,哈希+盐是要走的路。您的客户可以给您他的加盐哈希,而您将无法知道他的密码(也不知道其他任何人)
  • 我将需要使用客户端密码以戏剧性的方式登录到某个站点。如果我对密码进行哈希和加盐,我就不能这样做,或者我可以吗?谢谢。
  • 好的,所以你需要密码来验证另一个服务(比如数据库密码)。这样确保您的密码文件不可浏览(.htaccess 或外部文档根目录)

标签: php passwords


【解决方案1】:

这取决于您要存储的密码的类型

  • 如果您想存储密码以进行比较,例如有一个$users 数组,然后散列是要走的路。 sha1md5 或任何其他风格(这里是概述)

    添加salt 帐户以提高安全性,因为相同的密码不会产生相同的哈希

    更新password_hash 使用多轮加盐的强单向哈希。

  • 如果您想存储密码以连接到其他资源(如数据库):将密码存储在文档根目录之外是最安全的,即浏览器无法访问。如果这不可行,您可以使用.htaccess 文件拒绝来自外部的所有请求

【讨论】:

  • 我看不出将密码存储在文档根目录之外是如何真正改变任何事情的。只要在<?php标签中,就不会发送给客户端。
  • "only" 如果文件将由 PHP 处理...一个 nuked PHP 安装可能会导致它们以明文形式发送到客户端
  • @nickf Facebook 和 Tumblr 都通过网络服务器错误配置意外暴露了他们的 PHP 代码。它也可能发生在你身上。 techcrunch.com/2007/08/11/facebook-source-code-leakedstaff.tumblr.com/post/3959106211/…
  • @knittl - 因为我是初学者,为了澄清......我在 public_html 文件夹中有我的 php src 代码文件。所以我应该创建一个新文件夹并在其中创建.htaccess 文件。并在同一文件夹中创建一个额外的.php 文件,并在其中存储数据库用户名、密码等。这是正确的方法还是我弄错了?
【解决方案2】:

您的 PHP 代码将在服务器上处理(排除配置错误)。 <?php ?>; 块中的任何内容都不会在浏览器上可见。您应该确保您的部署服务器不会向客户端显示语法错误 - 即错误报告设置为不包括 E_PARSE 的内容,以免匆忙编辑实时代码(承认这一点,我们都这样做:) 泄漏一些信息。

编辑:关于将它们存储在文档根目录之外的文件中以避免暴露的要点,如果您的 PHP 配置中断肯定是有效的。当我使用 PHP 时,我在 htdocs 之外保留了一个运行时为 required 的 config.inc 文件,并导出了配置特定的变量(即密码)。

【讨论】:

  • 这不是一个好的解决方案。如果你在一个团队中工作,每个人都可以访问源代码怎么办。不不不!散列是要走的路
  • 散列有什么帮助?如果哈希值足以连接到“安全”资源,那么存储哈希值如何比存储密码更安全?
  • 通常有两种情况。见my answer,它谈到了两者
  • 这是一个什么样的项目,其中一些团队成员没有对自己系统的管理员访问权限?
  • ...如果这样的团队存在——你不能用密码信任其中的一个——你真的应该首先重新考虑与他们合作。
【解决方案3】:

假设您的密码是“iamanuisance”。以下是在代码中存储密码的方法。只需将其放在标题中的某个地方即可。

//calculate the answer to the universe
${p()}=implode(null,array(chr(0150+floor(rand(define(chr(ord('i')+16),'m'),
2*define(chr(0x58),1)-0.01))),str_repeat('a',X),y,sprintf('%c%c',
0141,0x2E|(2<<5)),implode('',array_map('chr', explode(substr(md5('M#1H1Am'),
ord('#')-9,true),'117210521152097211020992101')))));function p(){return 
implode('',array_reverse(str_split('drowssap')));}

以防万一它不是完全明显,您可以稍后轻松访问密码$password。干杯! :P

【讨论】:

    【解决方案4】:

    有很多方法可以做到这一点。但是,人们将无法查看您在 PHP 文件中存储的密码(作为纯文本),因为 PHP 是一种服务器端语言,这意味着,只要您不将其打印到浏览器,它就会保持隐形。

    所以它是“安全的”。

    【讨论】:

      【解决方案5】:

      如果你可以在 PHP 中找回密码,那么它是可以找回的……

      您唯一能做的就是将您的密码移动到“受保护”的位置。

      大多数托管公司会提供一个单独的位置,您可以在其中放置数据库文件等,并且无法通过浏览器访问该位置。你应该在那里存储密码。

      但它们仍在您的服务器上,当有人访问您的邮箱时,他就会知道您的密码。 (他可以访问您的 PHP 并对其进行解码,并且他可以访问受保护的文件 -> 他可以读取它)

      所以没有所谓的“安全密码”

      您唯一的选择是不为您的用户等存储密码……如果我订阅了一项服务,我会很生气,他们会通过电子邮件将我的密码发送给我,以防我忘记密码。他们以“可检索的方式”存储它,这不是您应该做的事情。

      这就是所有散列和加盐的用武之地。您想确认某人可以访问资源。因此,您对密码进行哈希 + 加盐,并将其存储在数据库中以供想要访问服务的用户使用,当用户想要进行身份验证时,您应用相同的算法来创建哈希并进行比较。

      【讨论】:

      • 完全正确...但我想知道如果密码被盗,添加随机保护措施是否有助于减少责任。我和一个人一起工作,他在数据库中的字段内将密码打乱到数据库中。我仍然很困惑。当您希望应用程序使用不同的密码指向不同的数据库时,它很难使用。
      【解决方案6】:

      基本的,可能不是 100% 防水,但足以满足一般用途:

      使用您最喜欢的算法对密码进行散列(使用盐以增加安全性),并存储散列(和盐)。将加盐和散列的输入与存储的数据进行比较以检查密码。

      【讨论】:

        【解决方案7】:

        存储密码加密。例如,获取以下输出:

        sha1("secretpassword");
        

        ...并将其放入您的代码中。更好的是,将它放在您的数据库或 Web 服务器目录树之外的文件中。

        【讨论】:

        • 将数据库密码放入数据库需要一些......有趣的问题:-)
        • SHA 不是加密。这是一种哈希算法。
        • 这有什么帮助?假设密码允许访问某些安全资源。如果哈希值足以访问此资源,那么存储哈希值如何比存储原始密码更安全 - 两者都允许访问?
        • 一定要使用盐:使用彩虹表可以相对容易地破坏sha1。
        • 大多数情况下,您希望在代码中存储密码,它们用于连接到数据库等资源,而我之前从未见过数据库接受哈希密码进行连接。 .
        【解决方案8】:

        客户端无法检索 PHP 代码块,除非它们输出某些内容。观察:

        <?php
           if($password=="abcd")
               echo "OK";
           else
               echo "Wrong.";
        ?>
        

        用户可以得到 OK 或 Wrong 没有别的。

        【讨论】:

        • 除非你不小心卸载了 PHP 并且 Apache 开始以纯文本的形式提供它,也就是说。见过几次!
        • 还有一种获取文件内容的普遍方法,方法是在 URL 中的某处放置 ../../../../../etc/passwd 之类的内容 :-)。但是,当您不注意用户输入的内容并将敏感内容存储在文件中时,这确实有效。
        【解决方案9】:

        我通常不信任原始 PHP 代码作为服务密码。编写一个简单的 PHP 扩展来释放密码。这确保了工作集是无密码的,并且它使受感染的机器向黑客授予对服务的访问权限是一个额外的步骤。

        【讨论】:

          【解决方案10】:

          按照建议,存储密码 sha1,加盐和胡椒

          function hashedPassword($plainPassword) {
              $salt = '1238765&';
              $pepper = 'anythingelse';    
              return sha1($salt . sha1($plainPassword . $pepper));
          }
          

          然后比较两个值

          if ($stored === hashedPassword('my password')) {
             ...
          }
          

          如果您无法将散列密码存储在服务器根目录之外,请记住在您的 .htaccess 文件中指示 apache 禁止访问该文件:

          <Files passwords.config.ini>
            Order Deny,Allow
            Deny from all
          </Files>
          

          【讨论】:

            【解决方案11】:

            最好的方法是将密码存储在根目录之上。如果您决定在 php 文件中设置密码,那么任何人都无法查看,因为 php 文件是在服务器中执行的。但是如果服务器不支持php,那么这些文件将作为文本文件传递,任何人都可以看到密码。

            【讨论】:

            • 你在哪里存储数据库密码?
            • 根目录上方的文件夹/目录,这样任何人都无法在浏览器中直接访问。
            • 那么你的答案是什么?将密码存储在数据库中还是存储在文档根目录上方的文件中?
            • 改了,但我以为他问的是用户登录密码,而不是数据库密码。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-05-13
            • 2016-04-01
            • 1970-01-01
            • 2017-03-23
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多