例如,在Django中有一个repo:https://sourcegraph.com/github.com/dcwatson/django-pgcrypto。
SQLAlchemy手册中有一些讨论,但我使用的是非字节列:http://docs.sqlalchemy.org/en/rel_0_9/core/types.html
我使用SQLAlchemy在Heroku上运行Flask。
非常感谢代码示例和/或一些讨论。
答案 0 :(得分:5)
这种决策有很多阶段,它不仅仅是“将插件插入堆栈并且加密事情得到了解决”
首先,您确实需要对每个专栏进行分类,以确定其对攻击者的吸引力。什么搜索/查询需要使用它,是否是连接列/索引候选者等。某些数据需要比其他数据更强大的保护。
考虑一下您试图保护 :
当然,还有app服务器,上游对编程语言和工具包的可靠来源的妥协等等。最终你达到了一个你必须说“我无法现实地抵御这一点”的地步。你不能防止有人进来,说“我来自政府,除非你允许我在这个客户的服务器上安装rootkit,否则我会向你做x / y / z”。关键是你必须决定你做什么必须防范,并根据这个做出安全决定。
一个很好的折衷方案是在应用程序中尽可能多地执行加密操作,因此PostgreSQL永远不会看到加密/解密密钥。尽可能使用单向散列,而不是使用可逆加密,当您进行散列时,正确地为您的散列加盐。
这意味着pgcrypto
实际上并没有给你带来太多好处,因为你永远不会向服务器发送明文,也不会向服务器发送密钥材料。
这也意味着对于列SecretValue具有相同明文的两个人在数据库中具有完全不同的SecretValueSalt, SecretValueHashedBytes
值。所以你不能加入它,有用地在WHERE
子句中使用它,有用地索引它等等。
出于这个原因,您通常会在安全方面妥协。您可以对部分数据执行未加盐的哈希,以便获得部分匹配,然后将所有结果提取到应用程序,并在应用程序端过滤它们,在那里您可以获得所需的完整信息。因此,您对SecretValue的存储现在看起来像SecretValueFirst10DigitsUnsaltedHash, SecretValueHashSalt, SecretValueHashBytes
。但是有了更好的列名。
如果有疑问,请不要发送任何对数据库敏感的明文。这意味着pgcrypto
对你没什么用处,你将主要做应用程序端加密。第一个原因是,如果您将明文(或更糟糕的是密钥材料)发送到数据库,它可能会在日志文件pg_stat_activity
等中公开。
您几乎总是希望将加密数据存储在bytea
列中。如果你真的坚持你可以对hex或base64进行编码并将其推送到text
列,但是以后必须使用你的系统的开发人员和DBA会哭。