适当的财务数据加密

时间:2017-07-05 07:40:37

标签: php mysql security encryption

我目前正在构建一个可以保存人员数据的Web应用程序(PHP / MySQL)。大多数此类数据不值得加密保护,但其中一些是财务信息,如收入等。它不是支付应用程序,也不会存储可直接转换为信用卡信息的信息,但仍然存在您不希望可能存在泄漏的信息。这个平台必须卖给那些想要"安全"的客户,但这可能意味着任何事情,因为客户自己不知道他们真正想要什么,因为他们是商务人士,而不是密码学家(就像我一样) )。

这是一个管理平台,因此保存其财务数据的人员不是平台的用户。该平台的用户仅仅是具有附加权限的登录。服务器本身永远不必访问数据。每个操作都由登录的用户(也可能是管理员)完成。多个用户需要访问相同的数据,因为他们有足够的权限。

我现在的问题是如何保护财务数据不受这些威胁的影响:

  • 有人发现SQL注入并远程转储所有表
  • 有人偷了服务器的硬盘(数据库+代码)

我当然不会去的地方:大规模嗅探攻击或服务器受损(比如嗅探服务器本身的SSL并不重要)或社交工程/网络钓鱼。

我还想快速总结一下,与当前系统相比,我需要存储多少信息(密钥,数据等),其中有一个简单的收入等字段和标准登录系统用户名和哈希密码。

编辑:几乎完全按照意见/答案的建议重新提出问题

3 个答案:

答案 0 :(得分:1)

以下是两种方法:

1)使用对称加密,因为您已经在客户端安排了密码,这是他们的密码。

每当用户需要访问其敏感信息时,他们都需要提供密码。如果需要,则可以使用该密码作为生成加密密钥的基础。

您可以使用PHP中的openssl函数加密敏感数据,并在客户端需要时对其进行解密。这将允许您选择OpenSSL支持的适当难以破解的算法。这样做的缺点是您需要明确的用户权限和密码才能访问该数据,如果您只是代表该用户存储它,那就很好,但如果您需要将其传递给其他人则很糟糕。

这样您就不需要在数据库中存储其他信息。如果有人窃取您的硬盘驱动器,他们将拥有加密的敏感数据和散列密码。缺点是它是单点故障,如果它们破坏了加密,它们也会获得密码,反之亦然,但是破解加密的难度并不像反转哈希那么高。它还依赖于强密码,正如我们所知,用户通常不会使用密码,但这不是一个新问题,而且我们今天也不太可能解决。

2)要求用户生成私钥 - 公钥对并向您发送公钥。然后,您可以存储此公钥并使用它加密数据。如果您有一个与您的服务器通信的应用程序/软件,这通常可以很好地工作,这可以代表用户执行此操作,但在Web应用程序中更难实现。也许有JavaScript库可以做到这一点,但由于它不是通常做的事情,你需要100%确定你使用的库是安全的。然而,这还要求用户将密钥存储在某处并且能够在他们想要访问该数据时使用它(同样,JavaScript可以为用户执行此操作,但由于安全性问题,保存和加载密钥需要用户交互。 )。

简而言之:

  1. 只有当加密密钥没有存储在服务器上时,对称加密才是安全的,但只要需要,用户就可以提供加密密钥。
  2. 非对称加密在针对普通用户的Web应用程序中更加安全但不切实际。
  3. 所以我建议使用用户密码作为密钥进行对称加密。

答案 1 :(得分:0)

除非用户自己生成并保留私钥的所有权,否则非对称加密和混合加密在这里毫无意义。我从你的问题的其余部分推断出情况并非如此。

假设您希望能够在没有用户交互的情况下查看此加密信息(例如,您不仅仅是为用户存储此信息,而且信息与您的业务运营相关),那么您的存储选项有限。 / p>

如果您的确切威胁模型是在数据库泄漏而没有其他的情况下保护此数据,则对称加密是完美的,如果正确实施的话。

这意味着对称密钥必须存储在向数据库发出请求并将数据提供给其他(可能是前端)系统的服务器上。如果这些服务器中的任何一个被泄露,那么加密的数据将被泄露。

总之,使用对称加密,但要了解它只会通过SQL注入或类似攻击等方式直接保护您免受数据库泄露。受感染的服务器是受损的服务器,通常意味着在足够的时间内完全访问数据。

编辑:如果您打算要求用户互动来查看安全数据,那么上面的apokryfos评论会准确详细说明如何保护信息。从用户密码生成对称密钥,并使用此密钥加密其他对称密钥。使用此辅助对称密钥实际加密数据。使用两个键可以更轻松地更改用户密码。

答案 2 :(得分:0)

从您的问题来看,以下要点脱颖而出。

  • 服务器本身永远不必访问数据。
  • 多个用户在拥有足够权限的情况下需要访问相同的数据。

  • 即使符合以下条件,也能保持安全:

    • 有人找到SQL注入并远程转储所有表。
    • 有人偷了服务器的硬盘(数据库+代码)。

这有可能实现,但不是微不足道的。使这成为可能的事情是服务器不需要访问数据。这允许我们使用用户密码来导出密钥。

权限结构中的每个级别都有一个关联的密钥。此密钥将用于加密可以使用这些权限查看的数据。创建第一个管理帐户时,为权限结构中的每个级别生成一个密钥,并使用管理密码作为KDF的输入并派生密钥。使用此密码派生密钥加密每个权限密钥,并将生成的密文存储在管理帐户旁边。

当管理帐户创建新用户并为其分配排名时,请提取新用户有权访问的最高级别权限密钥,以及权限较低的任何密钥,并使用管理密码对其进行解密(是创建用户所必需的,然后使用新用户密码再次加密它们,并与数据库中的新用户一起存储。

此系统允许您将所需的加密密钥传递给每个用户,并且无法以加密方式访问高于用户权限级别的数据。

此时,您可以通过简单地获取密码,解密相关权限密钥然后使用该密钥解密数据来允许用户访问数据。用户更改密码也很简单,因为它只是意味着您必须使用旧密码解密权限密钥,然后使用新密码重新加密。

在技术层面,我建议如下:

  • 使用AES。 AES-256往往是最常见的,但AES-128在宏观方案中同样安全。使用经过身份验证的块模式(GCM)并不重要,但仍建议使用。如果没有,请使用类似CBC或CTR的模式与HMAC。
  • 切勿直接使用密码作为密钥。使用PBKDF2从密码生成密钥。使用AES-256非常适合这里,因为你可以使用SHA-256作为PBKDF2的原语,并获得与内部哈希函数相同的输出。
  • 每次使用CSPRNG加密时都会生成一个新的随机IV。将IV加密到密文。不要像密钥那样从PBKDF2派生IV。