Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 如何使用pgcrypt在SQLAlchemy中实现列级PostgresSQL加密?_Postgresql_Heroku_Sqlalchemy_Pgcrypto - Fatal编程技术网

Postgresql 如何使用pgcrypt在SQLAlchemy中实现列级PostgresSQL加密?

Postgresql 如何使用pgcrypt在SQLAlchemy中实现列级PostgresSQL加密?,postgresql,heroku,sqlalchemy,pgcrypto,Postgresql,Heroku,Sqlalchemy,Pgcrypto,例如,在Django中,有一个回购协议用于执行此操作: SQLAlchemy手册中有一些讨论,但我使用的是非字节列: 我正在用SQLAlchemy在Heroku上运行烧瓶 非常感谢您提供一个代码示例和/或一些讨论。这类决策有很多阶段,不仅仅是“将插件推入堆栈,然后处理加密问题” 首先,您确实需要根据每个列对攻击者的吸引力对其进行分类&搜索/查询需要使用什么,它是否是连接列/索引候选项,等等。一些数据需要比其他数据更强大的保护 考虑一下你要保护的对象: 偶然攻击者(例如用于远程表拷贝的SQL注入

例如,在Django中,有一个回购协议用于执行此操作:

SQLAlchemy手册中有一些讨论,但我使用的是非字节列:

我正在用SQLAlchemy在Heroku上运行烧瓶


非常感谢您提供一个代码示例和/或一些讨论。

这类决策有很多阶段,不仅仅是“将插件推入堆栈,然后处理加密问题”

首先,您确实需要根据每个列对攻击者的吸引力对其进行分类&搜索/查询需要使用什么,它是否是连接列/索引候选项,等等。一些数据需要比其他数据更强大的保护

考虑一下你要保护的对象:

  • 偶然攻击者(例如用于远程表拷贝的SQL注入孔)
  • 被盗数据库备份(提示:也要加密)
  • 被盗/泄漏的日志文件,可能包括查询和参数
  • 具有直接非超级用户SQL级别访问权限的攻击者
  • 具有直接超级用户SQL级别访问权限的攻击者
  • 直接访问“postgres”操作系统用户的攻击者,以便他们可以修改配置、复制/编辑日志、安装恶意扩展、更改函数定义等
  • 在DB服务器上获得root权限的攻击者
当然,还有应用服务器,编程语言和工具包的可信来源的上游妥协,等等。最终,你不得不说“我不能实际地对此进行辩护”。你不能防止有人进来,说“我来自政府,我会对你做x/y/z,除非你允许我在这个客户的服务器上安装rootkit”。关键是,你必须决定你必须防范什么,并在此基础上做出安全决策

一个好的折衷办法是在应用程序中尽可能多地加密,这样PostgreSQL就永远看不到加密/解密密钥。尽可能使用单向散列,而不是使用可逆加密,并且在散列时,适当地为散列加盐

这意味着
pgcrypto
实际上对您没有多大好处,因为您从未向服务器发送明文,也没有向服务器发送密钥材料

这还意味着,两个列SecretValue的纯文本相同的人在数据库中的
SecretValueSalt,SecretValueHashedBytes
的值完全不同。所以你不能加入它,在
WHERE
子句中有效地使用它,索引它,等等

出于这个原因,您经常会与安全性妥协。您可以对部分数据进行非盐散列,以便获得部分匹配,然后将所有结果提取到应用程序中,并在具有所需全部信息的应用程序端对其进行过滤。因此,SecretValue的存储现在看起来像
SecretValueFirst10DigitsUnsaltedHash、SecretValueHashSalt、SecretValueHashBytes
。但是使用更好的列名

如果有疑问,不要发送任何对数据库敏感的明文。这意味着
pgcrypto
对您没有多大用处,您将主要进行应用程序端加密。原因之一是,如果您向DB发送明文(或者更糟糕的是,关键材料),它可能会在日志文件、pg统计活动等中公开


您几乎总是希望将加密数据存储在
bytea
列中。如果你真的坚持你可以对它进行十六进制或base64编码,然后把它放在
文本
列中,但是以后不得不使用你的系统的开发人员和DBA会哭。

每当你考虑加密时,你都不能把“如何”和“为什么”分开。你的目标是什么?您试图保护什么?保护谁?主要目的是在数据库备份“被盗”或数据库文件本身从服务器“被盗”的情况下,对这些列进行基本程度的加密保护。我希望这可以在代码不太复杂的情况下实现,同时避免由于错误的加密过程而无意中损坏数据的风险。感谢您深思熟虑的回答。我相信你的论点,日志等意味着加密可能属于应用程序。在我的例子中,这可能意味着将所有重要的文本列转换为字节类型并在应用程序上加密(但保持非信息性的数字连接键和行ID不变)。如果按照您所描述的方法(通过应用程序而不是数据库进行加密),是否有标准的方法来防止加密过程中的错误(例如,无意中临时使用了错误的密钥)对数据造成混乱?@user1642561可能有应用程序框架来帮助解决这一问题,但我不知道有什么东西可以集成到您正在使用的工具中。很抱歉关于这个问题,我想单独问一个问题。我可以请你澄清为什么应该使用bytea而不是字符串或文本列类型吗?@user1642561两个原因:1。加密数据在概念上不是文本字符串。它只是一个字节序列-它没有文本编码,它不是utf-8或拉丁语-1,它不代表任何字符。因此,对于干净的建模,应该使用字节类型。2.效率:如果你把它放在
text
字段中,你必须对这些字节进行编码,因为Pg的
text
字段不能存储
null
字节,而且并非所有的字节序列在所有的文本编码中都有效。您必须对其进行
base64
hex
或任何编码。然后,您就浪费了存储空间(bytea在磁盘上以1:1的比例存储为普通字节),并使其在概念上是错误的。