使用 Java 和 Postgres 数据库的客户端加密

Client Side Encryption with Java and Postgres Database

我已经对客户端每租户加密的实现进行了相当多的挖掘和研究,但我对如何继续我们的应用程序感到有点困惑。对于某些背景,我们有一个 dropwizard 应用程序,它有许多使用 jooq 在我们的 postgres 数据库中存储信息的自定义 DAO。我们的数据库有许多表、自定义函数和自定义用户定义的数据类型。我们的要求是我们客户的一些敏感数据需要加密(数据库表中的某些列)。数据按每个租户的行进行分区。

我知道我有两种选择将数据加密放在何处。

  1. 在我们的应用程序中
  2. 在我们的 postgres 数据库中

以下是我在探索上述两个选项时的发现:

虽然在我们的应用程序中进行加密是我最初的计划,但必须编辑每个 DAO 可能会导致很多问题并花费大量时间。

所以我研究了让数据库使用带有列端加密的 pgcrypto 处理加密的替代方案。但是,就像前面提到的那样,由于我们所有的列自定义数据类型,我无法为这些自定义数据类型列存储任何加密数据,因为加密数据作为 bytea 返回。修剪文档和其他堆栈溢出帖子除了更改这些列的数据类型以接受 bytea 与其自定义类型外,我无法找到解决方案,我希望尽可能避免这种自定义类型。

在此之后,我对如何最好地进行下一步感到有点困惑,因为我在此处列出的两个选项都会花费大量时间,并且可能会破坏我们的应用程序。

我的一些其他想法:

  1. 我已经研究过 jooqliquibase 进行加密但在那里找不到任何东西。
  2. 不是更新列的数据类型,而是创建一个新的加密版本的数据库,并使用视图来表示表的纯文本。

我的大问题:鉴于此处的背景信息,是否有任何建议或替代方案来实施客户端加密? (对我们当前架构的破坏最小)

谢谢! :)

如果您使用代码生成器将它附加到那些列,您可以轻松地使用 jOOQ Converter<String, String> 在所有需要的列上透明地实现您的 encryption/decryption。

示例:

public class EncryptionConverter extends AbstractConverter<String, String> {
    public EncryptionConverter() {
        super(String.class, String.class);
    }

    @Override
    public String from(String databaseObject) {
        return EncryptUtil.decrypt(databaseObject);
    }

    @Override
    public String to(String userObject) {
        return EncryptUtil.encrypt(userObject);
    }
}

此处有更多详细信息: