Tudor Golubenco:在PostgreSQL中使用pgcrypto实现多租户BYOK加密

Tudor Golubenco:在PostgreSQL中使用pgcrypto实现多租户BYOK加密

💡 原文英文,约1000词,阅读约需4分钟。
📝

内容提要

本文介绍在PostgreSQL中使用pgcrypto实现多租户BYOK列加密的方案。采用信封加密,AWS KMS保存客户密钥(KEK),应用从KMS解密获取数据密钥(DEK)并传入查询,数据库不持有密钥。通过示例展示单组织查询和跨组织混合查询模式,并强调密钥应作为参数传递、按行记录加密状态、非BYOK租户使用平台密钥等生产注意事项。

🔎

延伸解读

信封加密的职责分离

方案采用信封加密,将客户密钥(KEK)保存在AWS KMS,而实际加密数据的DEK由应用短暂持有并传入查询。这种设计实现了职责分离:KMS不接触数据,Postgres仅在查询执行时接触DEK,明文DEK只存在于应用内存中。这降低了密钥泄露的风险,即使数据库泄露,只要客户密钥未泄露,敏感数据仍然安全。

错误密钥的防护机制

pgp_sym_decrypt使用错误密钥时会抛出错误而非返回垃圾数据,这得益于PGP格式内置的完整性检查。这一特性对多租户场景至关重要,可以防止因密钥配置错误而静默返回错误数据,确保数据访问的可靠性和安全性。

生产环境的关键注意事项

文章强调了几项生产要点:密钥必须作为绑定参数传递,避免泄露到日志;加密状态应按行记录,而非依赖组织当前设置,以应对租户启用、禁用或轮换密钥的情况;非BYOK租户应使用平台管理的DEK,确保敏感列始终以密文存储;同时需规划密钥轮换并评估性能影响,仅加密敏感列。

Q&A

如何在PostgreSQL中使用pgcrypto实现多租户BYOK列加密?

使用pgcrypto扩展,结合信封加密方案。每个组织在AWS KMS中拥有自己的密钥加密密钥(KEK),应用从KMS解密获取数据加密密钥(DEK),并将DEK作为参数传入SQL查询,数据库不持有密钥。敏感列使用pgp_sym_encrypt和pgp_sym_decrypt进行加密和解密。

什么是信封加密?在本文中如何应用?

信封加密是一种加密方案,其中数据使用数据加密密钥(DEK)加密,而DEK本身又由密钥加密密钥(KEK)加密。在本文中,AWS KMS保存每个组织的KEK,应用从KMS解密获取DEK,然后使用DEK加密数据。KMS不接触数据,Postgres仅在查询执行时接触DEK。

在PostgreSQL中,使用pgp_sym_decrypt时用错误的密钥会发生什么?

使用错误的密钥调用pgp_sym_decrypt会抛出错误,而不是返回垃圾数据。这是因为PGP格式包含完整性检查,能够检测到密钥不匹配。

如何实现跨组织的混合查询,同时处理BYOK和非BYOK租户?

可以使用CTE(公共表表达式)携带各组织的密钥,并通过LEFT JOIN处理非BYOK行。例如,在CTE中定义每个组织的DEK,然后LEFT JOIN组织表,对于非BYOK组织(kms_key_arn为NULL),使用平台密钥或明文处理。

在生产环境中使用BYOK加密需要注意哪些事项?

注意事项包括:1) 密钥应作为绑定参数传递,避免泄露到日志;2) 按行记录加密状态,而不是依赖组织当前设置;3) 非BYOK组织使用平台管理的DEK,确保敏感列始终存储为密文;4) 规划密钥轮换;5) 只加密敏感列以减少性能影响。

为什么数据库不持有密钥?

数据库不持有密钥是为了增强安全性。如果数据库被泄露,攻击者无法直接解密数据,因为密钥存储在AWS KMS中,由客户控制。应用在查询时从KMS获取DEK,并仅短暂持有,从而降低密钥泄露风险。

🏷️

标签

➡️

继续阅读