我的应用程序需要访问一些敏感数据(在这种情况下是加密密钥)。此时我将它们存储在文件中,以便在处理脚本时可以读取它们。
但是,根据我必须遵循的安全标准,它还不够安全,因为如果服务器 root 帐户被盗用,有人可能很容易读取并复制它们。
典型的解决方案是挂载包含密钥的外部内存,启动应用程序,卸载内存并让缓存在内存中的数据运行。当然,因为它是 PHP,所以这是不可能的。
还有其他解决方案吗?在这一点上,我唯一的想法是带有密钥的小型应用程序,但是我不确定它应该如何工作才能安全。
正如您已经知道的那样,无论您做什么,如果该密钥对应用程序可用,那么在服务器上获得 root 访问权限的恶意代码肯定可以使用该密钥,并且最有可能获得对 UID 下的 UID 访问权限的代码该应用程序也运行。这只是一个简单的问题。
购买,因为您的应用程序不是长期运行的,听起来您将不得不接受超出此范围的风险。
您的想法是使用某种守护程序,将密钥保存在 RAM 中并且可以由应用程序查询。这行得通,但您可能已经意识到,如果您的应用程序可以查询它,那么恶意代码也可以查询它。如果您仍然选择该选项,请考虑使用memcached(为什么要重新发明轮子?)。
我能想到的唯一其他选择是编写一个 Apache 模块(用 C 语言),它在系统启动时加载密钥(之后卸载密钥的持久副本)和一个 PHP 扩展(用 C 语言)来获取来自位于同一进程中的 Apache 模块的秘密。假设您使用 PHP 作为 Apache 模块,而不是作为外部进程。但对我来说,这听起来有点矫枉过正,因为它非常复杂,实际上并没有消除风险。
您是否考虑过如何处理交换空间?您可以使用mlock
或类似(在 C 中)来防止将秘密写入交换,但是一旦将其移交给 PHP 解释器,就很难以这种方式保护它。所以你最好在没有交换的情况下运行系统。
考虑一项设计更改,它将密钥限制在长时间运行的守护程序(可能不是用 PHP 编写)中的单个位置,并让 PHP 应用程序将需要访问密钥的加密函数委托给该守护程序。