应用程序的数据加密与数据库中的数据加密

信息安全 加密 Web应用程序 数据库
2021-08-22 18:10:44

对于 GDPR(欧盟通用数据保护条例)实施,我需要加密一些个人信息。我们可以通过两种方式加密数据:

  • 让 Web 应用程序单独负责加密和解密。数据库中的实际数据是完全加密的。这样,如果数据被盗,数据是安全的(假设我的加密很好)。

  • 在数据库级别启用加密并将访问的 Web 应用程序添加为受信任的客户端。加密和解密发生在数据库本身。这样,如果数据库凭据已知,数据就会丢失。

那么在不影响性能的情况下,哪种方法最好呢?

3个回答

让您的数据库处理加密/解密可能是最好的:

  1. 您无需编写任何加密/解密代码并冒着意外破坏您自己的安全的风险。这也意味着,正如Guntram Blohm 指出的那样,如果归根结底,您不必证明自己的安全性是安全的。并且证明您的自定义软件的安全性和您可能认为的一样难,甚至更难。
  2. 使用内置到数据库中的东西通常更容易,例如Postgres允许您选择要加密的列和表,它们的设计只是简单地在服务器上包含密钥和解密的数据。其他数据库可能类似,但这是我熟悉的唯一一个。
  3. 例如,如果您需要根据数据生成报告,那么使用支持加密数据库的现有工具比在客户端自己编写所有自定义代码更简单。
  4. 如果您需要对不精确的、区分大小写的值的数据进行任何过滤,数据库将为您有效地处理它,例如维护索引但在需要它们之前保持它们加密,即使这样也只有在任何给定时间解密他们需要的特定值。

有一点支持您已经提到的客户端加密。这是一个很大的,但我不认为它超过了上面的好处:

  1. 如果您在客户端处理所有加密/解密,您的安全性将略微提高,因为数据库(以及任何控制该服务器的邪恶系统管理员/攻击者)在任何时候都不知道解密密钥或解密数据。但是,根据数据及其使用情况,有一些缺点需要考虑:
    • 您完全有可能弄乱您的客户端加密代码并以这种方式直接或通过侧通道泄漏数据/密钥
    • 您需要可以信任一个局外人或者手柄密钥管理自己,这是不平凡的(而且是非常不平凡的代码来支持,如果你想每隔一段时间,以避免停机时间安排)
    • 如果您确实弄乱了代码,那么您一个人(嗯,您的公司一个人 - 您知道我的意思)负责修复它并清理损坏,并且任何修复都可能像您的原始代码一样存在错误。可能更多,因为你会感到压力。
    • 您要么必须花费大量时间进行性能调整,要么接受您的性能会很差,或者降低安全性以轻松提高性能(例如,通过短路比较或预先计算一些常量或让编译器优化错误位)。这些都不是好事。数据库服务器已经有很多人在做很多调整;你会从头开始重做所有这些努力。
    • 对于每一个新开发人员,您都需要对他们进行良好的安全编码实践培训,或者告诉他们不要接触代码中与安全相关的部分,这两种方法都不具有成本效益,甚至通常都不那么可靠。
    • 如果您需要在客户端实现模糊过滤,您基本上将不得不SELECT * FROM table;手动解密和过滤每一行,这只是......不会顺利进行。您将把密钥长期保存在可直接通过网络访问的服务器的内存中,作为对攻击者可能发送的请求的直接响应。

正如Kevin 指出的那样,您还可以选择加密特定字段。例如,如果您要存储客户的用户名和信用卡号,则后者肯定需要加密,但前者可能不需要。例如,您可以包括一个CHECK约束,以确保您不会意外添加未加密的信用卡。信用卡号就是一个特别好的例子,因为您永远不需要对它们进行任何类型的匹配——您只需要从数据库中检索它们或将它们存储到数据库中,因此您可以从客户端有效地处理它们。

但是,请注意,良好的安全性不是一回事良好的安全性是正确的:

  • 分析您的威胁模型以确保您防范正确的威胁
  • 为您的整个网站使用 HTTPS,并使用有效的当前证书
  • 以一种或另一种方式加密您的数据库
  • 加密您的网站和数据库之间的通信
  • 正确使用 SQL 避免 SQL 注入
  • 强化您的数据库服务器以保护其免受攻击
  • 应用最小特权原则
  • 还有更多

无论您如何处理数据库,这都不是路的尽头。确保你照顾好一切

在其数据库的每个字段或每个字段组的基础上添加加密似乎是最好的折衷方案,前提是在每个字段被加密的同时还创建了一个索引字段。

你会一次解决几个问题。

  1. 搜索索引会一样快
  2. 并非所有字段都需要加密
  3. 加密开销保持在最低限度,重点关注 GDPR。
  4. 每个字段的不同密码可用于不同的最终用户,因为权限允许

最新趋势是将私钥存储在作为硬件安全模块的 HSM 中。有一些选项可以将密钥标记为不可从 HSM 中导出。需要加密的数据被发送到 HSM,但是如果数据量很大,它可能会影响性能。如果密钥是可导出的,它只会被导出并保存在内存中以供应用程序用于加密。导出密钥时,应首先使用 HSM 中的另一个公钥对其进行加密,然后将其发送到应用程序。由于应用程序有它的私钥,它可以解密我们的主加密密钥。现在的问题是这个密钥应该存储在哪里?它可以存储在访问受限的数据库中。