java - 在 Hibernate 中加密特定列:如何处理现有数据以及如何正确实现 @ColumnTransformer?
问题描述
我已经使用 MySQL 数据库构建了一个 Web 应用程序,该数据库包含患者数据。根据GDPR ,患者姓名必须在数据库内加密。为了连接和执行对 db 的操作,我使用 Hibernate 5。
在网上搜索,我发现了很多关于如何加密 db 表中的特定列或列的信息。主要有以下三种方法:
- 使用Hibernate
@ColumnTransformer
的注解,这对现有代码的破坏性最小,并且需要编写的代码最少 - 使用Jasypt及其 Hibernate 集成,这对现有代码更具破坏性,并且需要几行代码。
- 实现一个需要编写好几行代码的 JPA 属性转换器
我决定使用@ColumnTransformer
这似乎是最简单的实现。如果您认为其他方法之一更好,请说出来并解释原因。
然而,我的问题与现有数据有关。我的数据库已经有未加密的数据,必须对其进行加密才能与@ColumnTransformer
实现一起使用。我打算使用以下注释:
@ColumnTransformer(
read = "pgp_sym_decrypt(lastName, 'mySecretKey')",
write = "pgp_sym_encrypt(?, 'mySecretKey')"
)
和
@ColumnTransformer(
read = "pgp_sym_decrypt(firstName, 'mySecretKey')",
write = "pgp_sym_encrypt(?, 'mySecretKey')"
)
到相应的列。
我应该如何加密现有数据以符合上述注释?我应该使用什么 SQL 代码?
解决方案
MySQL 支持以下功能:
- AES_ENCRYPT(str, key_str);
- AES_DECRYPT(crypt_str,key_str);
但是,我无法使用以下内容更新所有 MySQL 条目(因为 aes_encrypt 返回二进制文件):
UPDATE Patient SET firstName=AES_ENCRYPT(firstName, "mySecretKey"), lastName=AES_ENCRYPT(lastName, "mySecretKey") //NOT WORKING
解决方案是:
使用 MySQL 命令重命名现有列:
ALTER TABLE Patient CHANGE firstName firstName-old; ALTER TABLE Patient CHANGE lastName lastName-old;
使用命令创建两个新的 MySQL 列
varbinary(512)
:ALTER TABLE Patient ADD COLUMN lastName VARBINARY(512) NOT NULL; ALTER TABLE Patient ADD COLUMN firstName VARBINARY(512) NOT NULL;
使用以下命令从旧列更新新列:
UPDATE `gourvas_platform`.`Patient` SET firstName=aes_encrypt(`firstName-old`, "my secret"), lastName=aes_encrypt(`lastName-old`, "mysecret");
现在我们可以安全地删除旧列
最后使用以下 Hibernate
@ColumnTransformer
注解:@ColumnTransformer( read = "AES_DECRYPT(lastName, 'mySecretKey')", write = "AES_ENCRYPT(?, 'mySecretKey')" )
和
@ColumnTransformer( read = "AES_DECRYPT(firstName, 'mySecretKey')", write = "AES_ENCRYPT(?, 'mySecretKey')" )
注意:因为我使用的是 MySQL 5.7 并且 AES_DECRYPT 函数返回binary[]
而不是String
,所以我需要输入cast
文本。所以上面@ColumnTransformer
需要改成如下:
@ColumnTransformer(
read = "cast(aes_decrypt(lastName, 'my secret') as char(255))",
write = "aes_encrypt(?, 'mysecret')"
)
和
@ColumnTransformer(
read = "cast(aes_decrypt(firstName, 'myscret') as char(255))",
write = "aes_encrypt(?, 'mysecret')"
)
推荐阅读
- vba - 永无止境 Do While...Loop VBA Word
- mongodb - 刚刚发布的最新的mongodb 4.2是稳定的新版本吗?
- internet-explorer - Github https 页面在 Microsoft Edge 和 Internet Explorer 中不起作用
- ios - 在旧版本上更新新版本的应用程序时,identifierForVendor 发生了变化。为什么?
- python - 使用 Python 将 JSON 嵌套到 CSV 设计
- python - 创建 QApplication 后如何导入 QtWebEngineWidgets
- apache - 为什么这条规则试图重定向到文件系统路径而不是 url?
- plotly.js - plotly.js - 不显示简单的静态图,但复杂的是
- sap-erp - 带有资产和使用寿命的 SAP 报告?
- angular - Ng 选择带有条件的下拉菜单