【问题标题】:Where should I store an encryption key for php?我应该在哪里存储 php 的加密密钥?
【发布时间】:2011-07-20 20:07:51
【问题描述】:

我正在编写一个接受敏感客户数据的 php 应用程序,因此我需要在将其存储到 mysql 数据库之前对其进行加密。我打算使用mysql内置的AES功能来做列级加密。

我想避免将加密密钥存储在服务器上,因此我将提供一个网页供管理员登录并输入加密密钥。我想在应用程序运行时将此密钥存储在内存中,但永远不会永久存储到磁盘。

最好的方法是什么?

我可以修改 $_SERVER 数组来存储请求之间的信息吗?我可以以某种方式将密钥存储在 apache 中吗?也许共享内存?

【问题讨论】:

  • 虽然我认为你的想法本身很糟糕,dev.mysql.com/doc/refman/5.0/en/memory-storage-engine.html
  • 如果机器自发重启(或者你需要重启它)会发生什么。钥匙会消失吗?或者应用程序处于脱机状态,直到管理员可以从某处的备份中查找密钥并手动输入。这可能是一个缓慢的过程。
  • 如果管理员不小心上传了错误的密钥或损坏的密钥会怎样?除非有人注意到,否则您存储的数据将永远无法检索,并且您不会知道哪些数据是用坏密钥生成的,哪些是用好的密钥生成的,除非您尝试解密每个部分并找出哪些数据不可恢复。
  • @genesis:我同意攻击者仍然可以查看内存内容,但我需要与客户的 IT 部门合作,他们不希望将其存储在文件中。
  • 最好不要使用 AES,因为许多服务器将其数据库存储在另一台服务器上,这意味着更多数据传输超出您的控制范围。最好在发送到 SQL 之前在 PHP 中加密。使用openssl 或更好的是最新的现成流行加密库。

标签: php security encryption administration


【解决方案1】:

与其依赖 MySQL AES 进行加密,不如使用 PHP 的原生 openssl 加密方案(PECL 扩展)。这需要一个私钥和一个公钥,公钥用于加密,私钥用于解密,并且可以将密钥保存在不同的地方。

【讨论】:

    【解决方案2】:

    我最终将加密密钥存储在内存表中。所有对数据库的访问都是通过一组存储过程完成的;存储过程包括进行密钥管理(即向内存表插入密钥、更改密钥、检查是否已输入密钥等)以及存储/检索应用程序数据的能力。

    通过这种设计,留在应用服务器上的数据库凭据只有通过定义的过程集进行查询的权限,而无法直接读取加密密钥。

    我喜欢这种方法,因为:

    1. 密钥未存储在文件系统中 - 防止硬件在报废时出现问题,并防止系统管理员窥探
    2. 应用程序代码无法访问密钥(除了在输入密钥时),因此它唯一驻留的位置是数据库进程中。
    3. 加密/解密的所有逻辑都嵌入在 SQL 查询中,因此无需担心应用程序代码是否正确 - 便于维护。

    【讨论】:

    • 服务器崩溃了怎么办?带key的内存表会丢失,你的数据不能再访问了?
    【解决方案3】:

    一种可能性是创建一个 RAM 磁盘并将密钥存储在那里。

    【讨论】:

      【解决方案4】:

      存储任何类型的加密密钥的最安全位置是在服务器上而不是在数据库中,并确保它由 root 拥有并且其他人无法读取。

      【讨论】:

      • 客户如何访问它?顺便说一句,数据库也在服务器上;)
      • 客户端不需要访问它。作者认为每次应用程序启动时由管理员重新上传密钥是一个好主意的假设是很糟糕的。一方面,如果管理员不小心弄错了密钥或一次上传了错误的文件,那么存储在其中的所有数据都将无法检索,没有人会知道哪些记录是用哪个密钥加密的。
      • @serialworm 您建议确保只有 root 可以读取文件,但 php 可能不会以 root 用户身份运行...
      • 好点。我确实注意到他提到他想避免将其存储在服务器上,但我知道将密钥存储在数据库中的危险。
      • AES 加密的重点是在您的数据库受到威胁时使您的数据无法读取。我通常会看到直接存储在配置或头文件中的 PHP 中的键和盐。这背后的基本原理是,如果有人正在查看您的 PHP,那么无论您如何存储它,您都已经丢失了,因为他们只需要找到您为进行解密而编写的函数调用。如果他们在途中发现了您的钥匙,那只是已经无法避免的损坏。
      【解决方案5】:

      编写一个 php 配置文件并将其存储在您的主目录中。只允许 php 访问它。

      $cryptKey = "aac1ebadcfabdef72376acd" ;
      

      包含在使用加密密钥的每个 php 页面的顶部,该加密密钥使用主文件夹的绝对路径。最终用户无法访问此文件夹。

      【讨论】:

        猜你喜欢
        • 2011-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-22
        • 2017-05-30
        相关资源
        最近更新 更多