在Postgres中存储加密数据

35

我有一个要求,需要在Postgres中以加密形式存储某些数据。显然,我需要对其进行加密、存储,并能够读取和解密它。那么,最好的方法是什么?


8
你的问题太过宽泛。你可以选择在 PostgreSQL 外进行加密/解密,或者使用 pgcrypto 模块在服务器内部进行加密。在这两种情况下,你可能需要使用 bytea 列或大型对象进行存储。 - lanzz
我认为pgcrypto模块可能是我想要的。 - Joe
1
问题太宽泛了。 - Honza Zidek
1个回答

45

最好的方式是在客户端或应用程序服务器上进行加密,这样数据库就不知道密钥是什么,也无法解密数据。如果客户端/应用程序服务器位于不同的主机上,那就更好了。

如果您的数据库为您加密和解密数据,则易受密钥与数据库一起被盗的风险。

如果您使用pgcrypto的内置数据库加密功能,可以让应用程序将密钥与数据一起发送,这至少有些帮助。然而,如果有一个乐于助人的系统管理员开启了激进的声明日志记录或自动计划转储,仍存在密钥暴露在日志中的风险;最终,如果密钥送到数据库机器,它们比不送更容易受到攻击。控制数据库机器的攻击者还可以更改日志设置、替换postgresql二进制文件,或通过嗅探流量来捕获密钥和数据。

如果应用程序服务器和数据库位于同一台机器上并由相同的角色管理,则没有太多分离它们的必要,直接使用pgcrypto可能更明智。

无论如何,记得添加盐值!


保留在服务器上?很多人说不要把密钥放在代码里?你是指只放在某个文件中吗? - Joe
7
是的,我会将它保存到文件中。如果你非常谨慎,可以将文件保存在可移动存储设备上,并让你的应用程序在应用服务器启动期间加载它,然后删除该文件,以便密钥仅保存在 RAM 中,而不可从硬盘访问。缺点是需要管理员干预才能重新启动应用程序服务器和恢复数据。对于那些特别担心的人,可以使用 JNI / JNA 来 mlock() 密钥所在的内存,以防止其被交换出去;并使用 SecurityManager 来限制意外属性访问等。坦白地说,如果攻击者已经达到了这个程度,那么你已经挂了。 - Craig Ringer
1
一个稍微简单的方法是将密钥保存在JECKS密钥库中,并由管理员输入密钥库的密码(最好是这样,但需要管理员干预才能重新启动),或者将其隐藏在某个不明显的文件中(虽然不太安全,但比未加密的密钥要好)。 - Craig Ringer
1
其实,我认为更好的方法是将密钥存储在存储过程中。然后给你的应用程序(或者任何你害怕会被盗取、阅读或反编译的内容)一个可以运行该程序但无法查看它的数据库登录帐户。(你必须删除 pg_proc 上的 SELECT 权限。) - Joe
5
我不同意Joe的观点——如果脚本存储在数据库中,备份中将以明文形式出现。备份的丢失或遭窃是安全漏洞的主要原因之一。此外,这也无法防止通过特权帐户(超级用户)对数据库进行未经授权访问,这些账户可以直接查看pg_proc。 - Craig Ringer
3
针对后来的搜索者:此问题还在 PostgreSQL 邮件列表上进行了讨论。http://archives.postgresql.org/message-id/1323354369.98656.YahooMailClassic@web161406.mail.bf1.yahoo.com - Craig Ringer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接