使用 PHP/PDO 存储数据的安全性



在研究了几个小时关于保护存储数据的主题之后,我对现在最好的方法有点困惑。

我的 (SSL) 网站有一个数据库,我是唯一可以访问它的人(黑客不计算在内)。登录数据存储在文档根目录之外的配置文件中。在数据库中,我有来自客户的姓名和地址之类的东西,我现在担心我需要实施密码学专家提出的所有安全措施,例如本答案(如何加密和解密PHP字符串?)或此处要求(将敏感数据安全地存储在数据库中)。

由于无论是在我的 PDO/SQL 和 PHP 研讨会上,还是在堆栈溢出的常规帖子中,我都看到这些加密和身份验证方法被使用,或者更具体地说,例如在解释 PDO 和 PHP 命令(如INSERT INTO ...等)时的密钥。我不确定现在是否有必要在我的数据库中的每个条目上部署加密和身份验证措施(之后是否可以这样做?我在教程和文章中被告知的安全措施是使用 PDO 准备好的声明。

如果加密和身份验证是我必须做的,可能是这样:对于每个敏感数据条目简单地使用password_verify()password_hash(),就像对密码所做的那样,这不是最方便,最快捷的方法吗?

EDITpassword_verify()password_hash()是散列(而非加密)方法,这意味着数据被不可挽回地破坏,只能确认但不能读取。

有不同类型的数据库加密,根据您要保护的数据以及原因,您将执行不同操作。

1) 数据库级加密/透明数据加密

这是您的RDBMS在文件级别为您加密所有内容的地方。这意味着如果有人可以访问硬盘驱动器或备份媒体,他们应该无法访问数据。有关如何使用MySQL进行操作,请参阅此处:https://dev.mysql.com/doc/refman/5.7/en/innodb-tablespace-encryption.html(请注意,这不是PCI兼容的解决方案,您需要MySQL企业版或其他企业数据库,或进一步的安全措施)。

请注意,如果您的应用程序遭到入侵,这不会保护您的数据。

2) 字段级加密

您可以加密要存储在您喜欢的任何字段中的数据。这里有一个很好的答案来处理这个问题:https://stackoverflow.com/a/10945097/

字段级加密的缺点是无法跨数据进行查询。在每种情况下,都需要将数据拉入应用程序,然后一次解密一个字段。

请注意,如果您的应用程序遭到入侵,这不会保护您的数据。

另请注意"加密"和"哈希"之间的区别(password_verifypassword_hash是关于哈希的)......加密可让您保护数据、存储和检索数据。根据定义,哈希不允许您检索数据。

在所有情况下,最重要的是保护您的应用程序。底层数据的加密是次要问题。

由于您的 Web 服务器(大概)必须
  • 有权访问数据,因此当 Web 服务器可以(必须能够)解密它时,静态加密它有些无用。为什么?因为Web服务器往往是薄弱环节。如果攻击者可以访问它,他们可以做任何可以做的事情,包括解密数据。

  • 加密静态数据仅用于防止反向通道泄漏,例如处理不当的备份(您正在这样做,对吧,对吗?),它将明文数据转储到文件中,然后无意中丢失在某个地方。为了防止使用数据库对客户端透明的任何静态加密;也就是说,如果它不是应用程序不可或缺的一部分,则它不是您应该给应用程序逻辑带来负担的事情,而是数据库应该担心的事情。

  • password_hash是一个哈希,它不会加密数据,它会不可挽回地破坏它,因此不可能从中取回原始数据。它非常适合存储您需要确认但未读取的凭据;对其他任何事情都没用。

  • 主要的安全点是"物理"隔离数据库服务器,即不授予除Web服务器以外的任何访问权;对此要非常严格和具体。这意味着弱点在那些入口点,如您的 Web 服务器。确保您的 Web 服务器尽可能被锁定,尽可能少地暴露攻击面(没有不必要的开放端口或正在运行的服务),并且在其上运行的应用程序代码不允许任何漏洞利用(是的,这是需要知识和纪律的困难部分)。

  • 您可以通过将数据库的访问权限与具有不同权限级别的不同帐户隔离来进一步收紧它;即某些帐户仅对某些表具有读取访问权限,而其他帐户对其他表具有读/写访问权限。如果您可以将 Web 服务器拆分为单独的角色,这些角色只需要特定的有限访问权限,这将通过避免一个部分中的漏洞从而在另一个部分中进行攻击来进一步增强安全性。

最新更新