encrypt/obfuscate 的想法导致 Presto 查询?

Ideas to encrypt/obfuscate results in a Presto query?

场景:

  1. 我有一个要查询和发送的 Presto table 结果给各种半信任方。
  2. 这些半信任方将分析数据和 return 结果 回到我身边。
  3. 此 table 中的一些数据是 "semi-private"— 没有什么可以 如果被发现会造成真正的伤害,但仍然是私有的(如设备名称)。
  4. 此 "semi-private" 数据的签名对于 GROUP BY 子句很重要,但实际数据本身对半信任方并不重要。
  5. 当此分析数据 return 返回给我时,我需要能够 decrypt/de-obfuscate 此 "semi-private" 数据才能对其采取行动。

问题:

是否有人熟悉一种方法 encrypt/obfuscate 纯粹在 Presto SQL 查询中的一列数据,稍后可以确定性地 decrypted/de-obfuscated ?

我知道我可以轻松 post 处理查询结果并 encrypt/obfuscate 自己处理,但如果可能的话,我想利用 Presto 的分布式执行模型。

encryption/obfuscation 的级别不需要是不可破解的——只是比 base64 编码复杂一点(最好有一个简单的秘密)。

我认为您可以提供自己的 UDF(用户定义函数),它可以进行一些对称加密。这里有如何实现此类功能的文档:https://prestosql.io/docs/current/develop/functions.html,这里有一些使用 Presto UDF 的示例项目。

然后在 Presto 中您可以:

SELECT decrypt_your_udf_function(private_column_encrypted, 'your password')FROM table;
INSERT INTO table (private_column_encrypted) SELECT encrypt_your_udf_function(private_column, 'your password') FROM ...

经过更多研究,我偶然发现了 XOR cipher,它似乎完全可以在 Presto DB 查询中实现。

我已经能够使用以下概念验证对其进行简要测试:

WITH

private_data AS (
  SELECT 'some private string' as private
),

encrypted_data AS (
  SELECT
  zip_with(
    regexp_extract_all(private, '.'),
    regexp_extract_all(substr('a27e6f329c03461688d6866203aasdljfasaslksa7982k3lkjsd987fok2jlkj0sdf9c59c', 1, length(private)), '.'),
    (x, y) -> 
      bitwise_xor(codepoint(cast(x as varchar(1))), codepoint(cast(y as varchar(1))))
  ) as encrypted_data
  FROM private_data
),

decrypted_data AS (
  SELECT
  array_join(
    zip_with(
      encrypted_data,
      regexp_extract_all(substr('a27e6f329c03461688d6866203aasdljfasaslksa7982k3lkjsd987fok2jlkj0sdf9c59c', 1, cardinality(encrypted_data)), '.'),
      (x, y) -> 
        chr(bitwise_xor(x, codepoint(cast(y as varchar(1)))))
    ),
    ''
  ) as decrypted_string
  FROM encrypted_data
)

SELECT
*
FROM private_data, encrypted_data, decrypted_data

它似乎可行,尽管我很想进一步简化它。任何人都可以看到优化它的方法吗? (例如:从长度为 1 的 varchar 转换为 varchar(1) 看起来很荒谬,但如果我不这样做它会抱怨。而且 regexp_extract_all 是我能找到的唯一方法将 varchar 转换为数组。)

我创建了一个示例项目,其中包含用于基本加密和解密的 UDF,您可以找到它 here。 以下是一些想法:

  1. 使用 AWS KMS 加密和解密数据。对于加密,如果我们可以动态获取 KMS 密钥 ID 而不是将其作为输入提供或存储在 jar 本身中,那就更好了。
  2. 如果成本太高,则替代方案是开发自定义加密逻辑并在 presto UDF 代码中使用它。