【问题标题】:Encryption at rest and/or AES_ENCRYPT静态加密和/或 AES_ENCRYPT
【发布时间】:2018-02-10 14:01:53
【问题描述】:

我正在尝试提高包含敏感数据的 MySQL 数据库的安全性。我正在努力掌握一些术语。如果我正确理解了情况,有人可以告诉我:

静态加密 - 看来我可以在表级别启用此功能。使用密钥加密表中的所有数据。如果有人掌握了备份文件或获得了对服务器的物理访问权限,那么数据将受到保护。当然,这假设密钥存储在其他地方。

AES_ENCRYPT - 在我的表中插入/更新数据时,我可以使用AES_ENCRYPT('data', 'password')。通过 SELECT 查询数据时,我使用 AES_DECRYPT

  1. 假设我只是使用 静态加密,那么我是否需要在我的 PHP 代码中做任何不同的事情来查询数据?我的 PHP 代码是否需要通过我的 PDO 请求将密钥发送到数据库?或者我可以使用我的普通代码查询数据库并自动处理解密?

  2. 或者我是否误解了静态加密的作用,我需要使用 AES_ENCRYPT 来代替/以及

【问题讨论】:

  • 静态加密仅意味着数据存储在不被使用的地方。因此,无论您加密整个表还是使用 AES_ENCRYPT 仅加密您将存储在数据库中的某些数据,这都是静态加密。我不是加密专家,但您可以使用 PHP 或 MySQL 进行加密。根据您在哪里进行加密,将决定您需要如何解密。
  • 好吧,在 MySQL 查询中使用 AES_ENCRYPT 会限制您使用可用的数据类型,您只能使用 VARBINARY、TINYBLOB、MEDIUMBLOB BLOB 和 LONGBLOB...您不能以这种方式设计好的表和索引...
  • @RaymondNijland 是的,我考虑过这个。使用“普通”表但仅将 AES_ENCRYPT 应用于通常不会被索引或在连接中使用的特定列是否正常?例如,用户表将具有 id、date_created、date_modified、address、email、telephone,然后只有 address、email 和 phone 应用了 AES_ENCRYPT。其他列没有加密?
  • 您可以加密一个字段中的数据,并在另一个字段中具有相同数据的哈希值。如果需要,您可以使用哈希字段进行任何索引或搜索。示例:$phone = '555.555.5555';然后 $hashPhone = youHashingAlg($phone);然后将 $hashPhone 存储在另一个字段的数据库中。然后,当您搜索 555.555.5555 时,使用相同的算法对其进行哈希处理。并搜索哈希值并返回整个记录以及必要时解密的数据。
  • @JadedCore 这完全不安全。制作自己的哈希算法根本不安全。它很容易被攻破,这样做会危及所有数据安全。不要尝试对数据进行哈希处理; 加密数据。 “搜索”加密数据本身就是一个复杂的雷区,需要非常小心地对待。

标签: mysql encryption


【解决方案1】:

静态加密

静态加密是数据库中未使用/访问或更新时的数据。移动中的加密类似于TLS,其中数据(来自数据库)从服务器传输到服务器到浏览器、服务器、浏览器等。在大多数情况下,TLS 非常好,如果它经过谨慎处理,并以您需要做的不仅仅是最低限度的态度来真正确保它真正安全。

一个典型的例子是人们在他们的域上放置了来自 LetsEncrypt 的 TLS 证书,并突然认为他们所有的东西都是安全的;但他们不加密他们的会话或他们的 cookie,所以在他们的防御中留下了一个巨大的潜在漏洞。

不要使用 MySQL 内置的加密系统。

这点我怎么强调都不为过; MySQL内置的加密系统不适合实际的安全数据保护。

请阅读my answer to a very similar question here 了解详情(我不想简单地复制/粘贴)。

好吧,那么,因为你坚持....这里:


我一直理解 不使用 MySQL 的内置加密功能,因为静态数据加密的要点(在 SQL 中)是,如果服务器受到破坏,数据不在 [风险。

MySQL 内置功能的问题在于,它不适用于数据在“at rest”状态下传入和传出的时间,因此可以记录任何数据的明文在 MySQL 日志中(以及存储系统上的其他地方,例如查询查找未加密,因此您可以从大量查找及其count 结果推断列值)之前/加密时。 You can read more about this here.

关于加密,你应该使用一些久经考验的库,比如defuse/php-encryption

根据我在自己对该主题的研究中所读到的内容,Magnus 提供的指向defuse/php-encryption 的链接是防止 MySQL 导致您破坏数据的最佳方法之一,永远不要让 MySQL 程序/服务器曾经看到你数据的明文值。

-- 2017 年 5 月 7 日发布的答案。


另外Bill Karwin's answer to the same question 提供了一些有价值的额外见解:

+1 对 Martin 的回答,但我会添加一些信息来说明它的价值。

MySQL 5.7 已为 InnoDB 表空间 (https://dev.mysql.com/doc/refman/5.7/en/innodb-tablespace-encryption.html) 实施静态加密。

据报道,MySQL 8.0 还将对 InnoDB 重做日志和撤消日志文件实施静态加密 (https://dev.mysql.com/doc/refman/8.0/en/innodb-tablespace-encryption.html)。

这仍然会留下未加密的查询日志和二进制日志。为此,我们将不得不等待 MySQL 的某个未来版本。

为什么需要这么长时间? MySQL 安全工程负责人在上个月 [2017 年 4 月] Percona Live 会议上的一次鸟语会议上表示,他们正在非常小心地实施加密权利。这意味着实现加密功能,以及密钥安全性和密钥轮换以及其他用途。做到这一点非常复杂,而且他们不想实施一些会被弃用并使每个人的加密数据库无效的东西。

-- 2017 年 5 月 7 日发布的答案。

结束点:

安全性很复杂。如果您想正确地做到这一点并且对保护洋葱皮有信心,那么您需要做很多事情(请参阅下面的项目符号);但您需要做的第一件事是:

  • 定义您要保护的对象

说真的。您需要不同的策略来对付想要窃取您的明文名称和地址的人、想要接管您的服务器的人以及仅仅因为想要丢弃数据的人。这是一个神话,你可以一直保护所有人,从概念上讲这是不可能的*;所以你需要定义最有可能的侵略者,然后找出如何最好地减缓他们的进步。

特别是对 MySQL,一些明确的建议:

  • 将 SQL 和 PHP 保持在同一台服务器上。不要远程访问 MySQL 数据。

  • 排除对 SQL 的外部访问(因此仅限 localhost

  • 混淆你的表名和列名;如果有人闯入您的数据并且您在username 列下有HDTBJ^BTUETHNUYT,那么他们知道这个乱码可能是用户名,因此他们在尝试破解您的加密方面有一个很好的开端。

  • 重要提示:真正锁定您的表访问权限;设置大量 MySQL 用户,每个用户只有最低限度的权限来做他们需要做的事情;您希望用户阅读表格()并且只阅读某些表格;用户写入某些表但无权访问其他表。如果 MySQL 上的任何一个用户受到威胁,这是一个单独的关注点;您并没有自动丢失其中的所有数据。

  • 使用 PHP 加密服务。将加密密钥存储在一个完全独立的地方;例如,有另一台您仅用于备份的服务器,您只能访问该服务器以获取加密密钥,因此如果您的 PHP/MySQL 服务器受到威胁,您有一些空间可以切断和锁定密钥服务器,这样您就可以限制伤害。如果密钥服务器也有备份,那么实际上你并没有受到严重损害(取决于情况)。

  • 设置大量观察者和电子邮件通知者,以准确告诉您某些进程何时运行以及哪些服务器用户(不是人,而是程序)在做什么。因此,您可以看到为什么一个意外的进程会在凌晨 5 点开始运行以尝试测量 MySQL 表的大小。什么鬼?

  • 即使您的 MySQL AES_ENCRYPT 数据未在数据库中静止,也有很大可能“嗅探”该数据,但如果网站遭到入侵(或者更糟糕的是,PHP 代码不安全),那么定时攻击可以通过定时查询查找和数据包返回来计算出数据内容。

  • 安全是一个黑洞;在某些时候,你会想“这个,我已经做得够多了”。没有人拥有完全的安全性,一些非常敬业的组织拥有足够的安全性。在你走远之前,你需要计算出你愿意走多远。


* 为什么不可能?因为要始终保护您的数据免受所有威胁,它需要像哈希一样不可读、不可用。哈希始终受到所有人的保护。但是哈希永远不会被取消哈希。

【讨论】:

  • 这很棒而且很有帮助。谢谢你。我会重新阅读并消化所有内容,但是您的论点摘要是否公平?建立一个常规的 MySQL 数据库,使用 defuse/php-encryption 加密/解密特定的包含敏感数据的列,遵循帖子末尾的其他要点,然后特别注意创建具有非常特定权限的多个 MySQL 用户.远离我的 MySQL 提供的任何加密,不要使用 AES_ENCRYPT。再次感谢您
  • @Chris 是的,但老实说,最重要的是安全性可以一直持续下去,这是一个永无止境的故事——你需要确定你正在反对什么样的妥协,然后针对此类攻击定制您的安全措施。
  • 是的,当然。我只是渴望获得一个良好的基础,然后在此基础上再接再厉。
  • 尽可能多的关注点分离——没有一个用户/单元/代码库拥有超过它绝对需要的访问或控制。始终只授予对所有内容的最低访问权限。
  • 知道了。这是通过在数据库中加密数据来实现的,解密它的能力受到谁(需要)访问适当密钥的限制。此外,每个用户的数据库权限都被锁定到最低限度
猜你喜欢
  • 2011-11-26
  • 2015-09-23
  • 2021-11-29
  • 2011-06-20
  • 1970-01-01
  • 2014-10-22
  • 1970-01-01
  • 1970-01-01
  • 2023-01-20
相关资源
最近更新 更多