【发布时间】:2020-07-16 20:32:51
【问题描述】:
我遇到了一个问题。使用psycopg2 从表中的加密列中进行选择。
在使用
create table users (
id BIGSERIAL NOT NULL PRIMARY KEY,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(100) NOT NULL,
secret_val_1 BYTEA,
secret_val_2 BYTEA
);
我能够在其中插入加密值。
现在我正在尝试使用psycopg2 查询表中的值:
cur.execute("""
SELECT PGP_SYM_DECRYPT(%s::BYTEA, 'compress-algo=1, cipher-algo=aes256')
FROM users;
""",
('secret_val_1',))
现在这会引发错误:
ExternalRoutineInvocationException: Wrong key or corrupt data
有趣的是,当像这样传递值时,它可以工作:
def query_users_decrypt(col):
cur.execute("""
SELECT PGP_SYM_DECRYPT({}::BYTEA, 'compress-algo=1, cipher-
algo=aes256') FROM users;
""".format(col),
(col,))
但这对于 sql-injection 攻击并不安全,对吧?
有谁知道如何正确地做到这一点?谢谢!
【问题讨论】:
-
您想在查询中完成什么?您发送的
'secret_val_1'是什么?format()版本不应该工作,因为你需要单引号包围它。如果你的秘密值看起来像'\xc30d040...',那么在它前面放一个r来生成一个原始字符串(例如r'\xc30d040...'。查询将返回等于users中的行数的行数表,每个表都有一列,其中包含您传入的任何内容的解密形式。 -
您好,感谢您的 cmets。我只是想从表中查询并解密列
secret_val_1。对于所有条目。奇怪的是format()方法对我有用,但我知道它不安全。不幸的是,使用r'secret_val_1'选项给了我同样的错误。我不确定我在这里错过了什么...... -
哇!我明白为什么
format()现在可以工作了。您将文字secret_val_1传递给格式,以便替换列名。我会给你一个答案。 -
抱歉,可能不清楚,因为在我的代码中,我将查询包装在一个函数中。我更新了它,这对我来说是这样的。
标签: python sql postgresql psycopg2 pgcrypto