如何在 Spring Data JPA 和 Hibernate 中加入加密列和普通列?

问题描述 投票:0回答:1

我在数据库(PostgreSQL)中有两个表,两个表都有一个作为主键的

id
字段,一个公共
example_id
和其他字段。

A { id, example_id, first_name, last_name } <- Here example_id is always encrypted
B { id, example_id, qty, beds } <- Here example_id is always in plain sight

当我从 A 插入和读取数据时,我使用

@ColumnTransformer
注释来使用
pgcrypto
内置函数对
example_id
字段进行编码和解码。

@ColumnTransformer(
  forColumn = "example_id",
  read = "pgp_sym_decrypt(example_id, 'my_key')",
  write = "pgp_sym_encrypt(?, 'my_key')"
)
private String exampleId;

现在的问题是:如何在

example_id
字段上执行两个表之间的 JOIN?是否有 JPA 注释可以在执行匹配之前动态加密或解密列?可以在DB级别完成吗?或者我是否需要创建自定义 JPA 查询或将逻辑移至应用程序级别?

提前致谢

java postgresql spring-boot hibernate jpa
1个回答
0
投票

最终我通过简单的OneToOne关系解决了这个问题,底层框架自动执行加密值的读写。 它不会加密明文并比较密码,而是自动读取并解密第 i 条记录中的加密密码并进行比较

但是,为了使其工作,我必须使用底层数据库的 current_setting 函数来纠正加密密钥的管理,因为不可能将环境密钥动态且轻松地注入到 JPA 注释中。此外,我必须指定安装

pgcrypto
函数的架构。

@ColumnTransformer(
  forColumn = "example_id",
  read = "public.pgp_sym_decrypt(example_id, current_setting('encryption.key'))",
  write = "public.pgp_sym_encrypt(?, current_setting('encryption.key'))"
)
private String exampleId;

为此,我必须访问 postgresql.conf 文件并添加 encryption.key 属性,以便 current_setting 函数在数据库级别找到密钥。

encryption.key = 'my_key'

但是,请小心,因为密钥以明文形式存储在数据库中。最好通过函数或存储过程从外部系统检索它。

© www.soinside.com 2019 - 2024. All rights reserved.