繁体   English   中英

从 MySQL 纯数据库值迁移到完全 AES 加密的值 (PHP APi)

[英]Migrating from MySQL plain database values to fully AES encrypted values (PHP APi)

短的:

由于 GDPR 法规,从纯文本数据库值迁移到完全/完全加密值的最佳方法是什么?

讲解员:

我刚刚收到一个“提示”,由于 GDPR(欧盟通用数据保护条例)法律要求的新“设计隐私”概念,所有“敏感”信息都需要加密。 这包括姓名、地址、社交媒体资料、..

我们目前正在为 2000 多个用户运行一个完整的生产数据库,只能通过我们的 PHP REST API 访问,该 API 用作所有 Web 和移动应用程序的入口点(尚无第三方开发人员)。 该数据库包含当前以纯文本形式存储的电子邮件地址、地址、社交媒体句柄、名称、IP 地址......(除了基于安全的敏感信息,如密码、令牌......或用于身份验证的任何其他值/鉴别)。

我不是这个(开发明智的)的忠实粉丝,因为它对性能、搜索算法、整个 PHP API 等的主要影响(感觉就像整个优化和“完美设置数据库”的结束),但因为它是必需的因为它是额外的保护层,所以我全力以赴。

现在,我主要关心的是..一切都在积极运行,我们不能只是说“好吧,关闭服务器,加密一切,部署新的 API 版本并重新打开它。”。 此外,我认为这种迁移不能“一步一步”完成,所有事情都必须一次完成。 如果 API 未准备好处理所有查询中的解密,则无法加密数据库值,反之亦然,如果 API 期望对所有内容进行加密,则数据库不能是纯文本。

(我很高兴我将整个 API 类型的交易作为数据库的唯一入口/读取点,没有自定义脚本/连接,所以这是一种解脱)

我们正在运行一个功能强大的 VPS 服务器,因此由于冗余检查和诸如此类的东西是一种选择,因此会造成一些性能损失,而且我们也在运行暂存/开发环境,因此测试没有问题。

例如,我会让 MySQL 使用基于 ID(主键)和创建时间戳的组合的每个记录的唯一键来处理 AES(这两个值都不会改变)(这可能不是那么聪明)想法万一“出于某种原因”这个值确实改变了,数据消失了..所以不确定),所以我的PHP应用程序在运行查询时不需要以纯文本形式传达密钥,但又一次, “创建用于解密的密钥”仍将在查询日志等中可见,因此“最安全”的方法是让 PHP 应用程序加密和解密所有传入/传出数据,但这将导致无法例如,运行“搜索查询”(除非我在这些特定查询中发送密钥......)。

我的问题:

怎么办呢..? 我应该让 PHP 处理加密/解密还是更可取的 MySQL? 当记录被请求时,是否有一种可用的方法可以沿途迁移到加密值? ..?

我的想法是不接触任何数据库值(除了更新每个非整数列以处理当前指定的字符数量的 2-3 倍),这可以在不影响生产的情况下完成。 然后逐步更新所有 API 查询,以检查所选值是否已加密。 当一个部分运行正常时,更新该部分的表以加密所有值。 作为一个(简单的)例子

MySQL方式; 每个 SELECT 查询:

SELECT IF_AES_ENCRYPTED(first_name, AES_DECRYPT(first_name), first_name) AS first_name FROM contacts WHERE id = 1;

(或)PHP 方式:检索数据:

while ($row = $result->fetch_assoc()) {
  $contact->setFirstName((IS_AES_ENCRYPTED($row['first_name']) ? AES_DECRYPT($row['first_name']) : $row['first_name']);
}

在部署结束时:

UPDATE contacts SET first_name = AES_ENCRYPT(first_name);

肯定有方法可以做到这一点,但由于我是此时唯一的开发人员,我只是不确定最实用/最有效的方法是什么,或者我是否过度或低估了这一点或不。 只是寻找其他已经执行过这样的迁移/更新的开发人员。

谢谢,伯特。

我会通过添加一个新列first_name_enc来存储字符串的加密版本来做到这一点。

然后,您可以在过渡到完全加密时临时存储加密和未加密的值。

ALTER TABLE contacts ADD COLUMN first_name_enc VARBINARY(...);

当您读取值时,对其进行解密,但如果该值为 NULL,则它必须是尚未转换的行,因此请回退到原始未加密列。

SELECT COALESCE(AES_DECRYPT(first_name_enc, <key-string>), first_name) ...

在整个应用程序中放置此代码后,您就可以开始批量转换行:

UPDATE contacts SET
  first_name_enc = AES_ENCRYPT(first_name, <key-string>), 
  first_name = NULL
WHERE id BETWEEN 1 AND 1000;

完成将所有内容转换为加密后,您的应用程序不再插入未加密的列,然后您可以将条件查询转换为简单地读取加密列并解密它们。

SELECT AES_DECRYPT(first_name_enc, <key-string>) ...

然后最后删除未加密的列,因为它们现在只包含 NULL 值。

ALTER TABLE contacts DROP COLUMN first_name;

我建议您在投入时间从事这项工作之前确认您真正需要做的有关加密的工作。 我读过一些文章声称 GDPR 实际上并未强制要求加密。 https://www.i-scoop.eu/gdpr-encryption/

但对互联网文章持保留态度。 咨询合格的专家。 即使向专业专家支付咨询费,也可能为您节省数万美元的软件开发成本!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM