首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在PostgreSQL中使用aes加密?

如何在PostgreSQL中使用aes加密?
EN

Database Administration用户
提问于 2012-09-15 18:35:41
回答 1查看 49.2K关注 0票数 17

我使用以下语句尝试aes加密:

代码语言:javascript
复制
SELECT encrypt('test', 'key', 'aes');

这起作用了,但我无法解密这个值。我把它插入了一个数据类型字段,但是我不确定这是不是正确的方法。

代码语言:javascript
复制
SELECT decrypt(pw, 'key', 'aes') FROM table WHERE ID = 1;

给了我错误

错误:函数解密(字节,未知,未知)不存在第1行:从ID =7的表中选择解密(pw,'key','aes');^提示:没有函数匹配给定的名称和参数类型。您可能需要添加显式类型转换。

这是否真的意味着encrypt()是一个现有的函数,而不是解密()?不然我怎么能收回aes加密的值呢?

EN

回答 1

Database Administration用户

回答已采纳

发布于 2012-09-16 04:57:11

psql中的\df *crypt揭示了pgcrypto encryptdecrypt函数(PgCrypto文档也是如此)的参数类型:

代码语言:javascript
复制
                                List of functions
 Schema |      Name       | Result data type |   Argument data types    |  Type  
--------+-----------------+------------------+--------------------------+--------
 ...
 public | decrypt         | bytea            | bytea, bytea, text       | normal
 public | encrypt         | bytea            | bytea, bytea, text       | normal
 ...

因此,encryptdecrypt函数都期望密钥是bytea。根据错误消息,“您可能需要添加显式类型强制转换”。

然而,它在这里很好的第9.1,所以我怀疑它有比你已经显示的更多。也许你还有另外一个函数,也叫encrypt,它有三个参数?

下面是它在一个干净的P9.1上的工作原理:

代码语言:javascript
复制
regress=# create table demo(pw bytea);
CREATE TABLE
regress=# insert into demo(pw) values ( encrypt( 'data', 'key', 'aes') );
INSERT 0 1
regress=# select decrypt(pw, 'key', 'aes') FROM demo;
  decrypt   
------------
 \x64617461
(1 row)

regress=# select convert_from(decrypt(pw, 'key', 'aes'), 'utf-8') FROM demo;
 convert_from 
--------------
 data
(1 row)

Awooga!阿乌加!关键暴露风险,需要极端管理警告!

顺便说一句,请仔细考虑一下PgCrypto是否真的是正确的选择。查询中的密钥可以在pg_stat_activity中显示,系统日志可以通过log_statement显示,也可以通过密码语句显示,如果出现错误,则会失败。通常情况下,在应用程序中做密码比较好

在启用client_min_messages的情况下,见证这个会话,这样您就可以看到日志中的内容:

代码语言:javascript
复制
regress# SET client_min_messages = 'DEBUG'; SET log_statement = 'all'; 
regress=# select decrypt(pw, 'key', 'aes') from demo;
LOG:  statement: select decrypt(pw, 'key', 'aes') from demo;
LOG:  duration: 0.710 ms
  decrypt   
------------
 \x64617461
(1 row)

哇,如果log_min_messages足够低的话,可能会在日志中公开密钥。它现在与加密数据一起存储在服务器上。失败。如果出现错误导致语句被记录,或者如果启用了log_statement,则在不使用auto_explain的情况下也会出现相同的问题。

通过pg_stat_activity暴露也是可能的。举行两次会议,并:

  • S1:BEGIN;
  • S1:LOCK TABLE demo;
  • S2:select decrypt(pw, 'key', 'aes') from demo;
  • S1:select * from pg_stat_activity where current_query ILIKE '%decrypt%' AND procpid <> pg_backend_pid();

哇哦!钥匙又来了。它可以在没有LOCK TABLE的情况下由无特权的攻击者复制,只是很难对其进行正确的时间安排。通过pg_stat_activity进行的攻击可以通过从public撤销对pg_stat_activity的访问来避免,但它只是表明,除非您知道应用程序是唯一访问它的东西,否则向DB发送密钥可能不是最好的方法。即使如此,我也不喜欢。

如果是密码,你应该把它们存起来吗?

此外,如果您正在存储密码,则不要对其进行双向加密;如果有可能,则对其进行散列并存储结果。您通常不需要恢复密码明文,只需确认所存储的散列是否与用户发送给您的密码匹配,当使用相同的盐分进行散列时。

如果是

,让别人为你做

更好的是,根本不要存储密码,使用LDAP、SASL、Active Directory、OAuth或OpenID提供程序或其他已经设计和工作的外部系统进行身份验证。

资源

还有更多。

票数 20
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/24370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档