我正在考虑加密我的数据库和/或仅加密几个表中的某些列。值得花时间吗?我的意思是,如果有人要获得我的加密数据库,他们会有多大的负担?有没有人找到解决这个问题的方法?
SQL 字段级加密,安全性如何?
如果您对在 SQL Server 2005 及更高版本中使用列级加密感兴趣,我有一堆示例代码,说明如何使用 SQL Server 中的内置加密功能来保护敏感数据。代码都可以在http://sqlcrypto.codeplex.com/
在代码中,我展示了如何加密敏感数据并确保只有授权用户才能解密它。我利用内置的密钥管理功能,并拥有由数据库引擎管理的强大的随机生成的对称 AES 密钥,然后这些 AES 密钥通过证书进行保护。数据库角色控制谁可以访问哪些密钥,并且使用内置的 SQL Server 加密,您甚至可以使用密码来额外保护密钥或证书,这样如果数据非常敏感,您甚至不必信任您的 DBA。话虽如此,如果您不信任您的 DBA,那么您还有其他问题 :)
由于 SQL Server 通过加密(确保唯一的 IV)做正确的事情,如果不进行表扫描并解密每一行以查看是否存在匹配项,则无法搜索加密列。我提供了一些用于构建加密数据 HMAC 的示例代码,以便您至少可以进行基本搜索而不会泄露明文信息。
我还有一些示例,说明如何使用内置的散列算法(不足以用于生产用途)和 bCrypt 散列算法的 SQLCLR 实现来存储密码的加盐、拉伸散列,以实现更好的密码存储。
还有一些示例代码展示了使用透明数据加密来加密磁盘上数据和日志文件的全部内容。
使用内置加密的一些优点是:
- 出色的密钥管理,服务器在生成加密密钥时做正确的事,并使用多级加密来保护密钥
 - 正确加密服务器确保每次写入每条数据时都使用 nonce IV 加密,这意味着有人无法查看两个加密值并确定它们是相同的明文值。
 - 加密列的可选完整性检查,以确保某人不能只用另一个加密值覆盖加密值
 - 可移植性,您可以从多个平台访问您的数据,而无需处理因平台实现不同而工作不同的问题。
 - 良好的静态数据安全性,加密是在任何日志或数据页写入磁盘之前完成的,因此记录的任何数据都不包含明文。
 - 能够轻松遵循最小权限原则,并且仅将加密密钥的访问权限授予需要它们的角色和/或用户。
 
编辑:有关Microsoft SQL Server的特定信息,请阅读下面的@Joe 评论。还,
我希望虽然您描述的功能会加密二进制日志(或类似的功能,如入侵文件系统),但如果有人使用 SQL 注入访问数据可能无济于事,因为解密的自动性质。我认为您应该将敏感信息打包到单独的 SQL 用户中(并限制主用户),或者您可以添加额外的加密/散列层。
更不用说仔细检查你的 SQL 注入预防了。
如前所述,加密数据库的计算成本更高,更不用说编程工作了。
几点建议
如前所述,请加密敏感信息,如密码(可用于获取其他帐户的更敏感信息)或信用卡号、SSN(当然)。如果您不需要解密(例如,只需将一个加密密码与文件中的密码进行比较,则无需解密),则使用散列函数。
为了降低 SQL 注入风险,请查看您的 SQL 用户访问权限。系统的身份验证部分可以与系统的其余部分分开。这可能是更仔细审查和更少修改的代码量少得多。
如果您使用强大且推荐的例程(例如 AES)和全长随机密钥(不仅仅是简单的密码短语)加密数据,那么没有密钥数据将变得无用,除了可以检测重复项等基础知识,您可以计算行数,查看它与未加密信息的关系等。
入侵者可能获得的不仅仅是数据库。如果入侵者可以访问您的数据库和密钥(例如,如果它被硬编码到您的程序中),那么它几乎是无效的。如果需要,您可以考虑一个复杂的模型,该模型可以防止将密钥存储在 plain 中。如果您正在改造现有系统,这当然是高度相关的。
不要使用 SQL 内置的加密函数。如果入侵者获得对您的数据库和 binlogs 的访问权,您将遇到类似的问题。(SQL 语句日志,例如在 MySQL 中) SQL 内置例程在语句之后进行评估,将明文参数复制到 binlogs。您应该坚持程序内加密以防止这种普通版本的泄漏,它进入语句日志(bin-logs,slow-logs),也可能泄漏到进程列表中。
但真的
- 您应该首先确保没有 SQL 注入。
 
以及其他更明显的漏洞。硬化你的外壳似乎是一种更经济的投资。
- 修补面向 Web 的服务,
 - 禁用未使用的检修门,
 - 还包括访问列表是防止不受信任的 IP 地址或非 VPN 用户利用漏洞的好主意(更不用说它可以减少负载,这有助于防止拒绝服务攻击)
 
加密是潜在的有价值的后续防线/减少责任。
但即使是我提到的复杂模型,也只是最薄弱的环节。
- 很多人真的只用一个词作为他们的密码,
 
你可能会发现你错过了一些东西,比如
- 没有使用足够慢的哈希例程,或者
 - 没想到入侵者会在短时间内租用一个破解集群。
 
但是你仍然应该尽最大的努力。
理想情况下,您的计算机只会提供允许的内容,并且存储加密将毫无意义。这种情况很少见。
请注意,此答案仅关注直接黑客攻击,而不是物理访问,或通过您的系统管理员的一台 PC 进行访问。
密码学通常不是问题。在大多数情况下,加密整个数据库几乎肯定是浪费时间。
通常有一些非常重要的值应该被加密。一个经常被忽略的值是会话 id、csrf 令牌、密码 salt 和忘记的密码令牌。如果您愚蠢地将会话 ID 存储在数据库中,那么具有 SQL 注入缺陷的黑客可以提取此值并登录,而无需破解密码哈希。
正如其他用户已经说过的那样,加密整个数据库可能是多余的,这意味着您将失去太多性能而获得的额外安全性很少,因为您将加密不需要加密的字段。
可以这样想:假设攻击者通过 SQL 注入设法访问了您数据库中的所有数据。攻击者绝对不应该看到哪些信息,哪些信息不那么重要,这意味着即使他可以阅读它,他也无能为力?第一种类型的示例是用户的密码,第二种类型的众多示例之一可能是用户最喜欢的颜色,如果出于某种原因您需要将此信息存储在数据库中:D
因此,加密整个数据库不值得花费时间和性能损失,但有些字段绝对需要加密(密码、信用卡号、SSN、会话 ID,您还可以将个人用户信息添加到此列表中,像电话号码等,您的用户将不胜感激:))。
不要忘记,如果攻击者可以访问您的数据库,即使某些字段已被加密,他最终也可以访问其中的所有信息,他只是需要更多时间来完成。如果您的数据库中有非常重要的信息,那么这段额外的时间就非常重要。
最后是一个建议:花时间防止 SQL 注入攻击。这可能是攻击者可以非法访问您的数据库的最常用技术。