\df *crypt
у psql розкриває типи аргументів pgcrypto encrypt
та decrypt
функцій ( як це роблять документи PgCrypto ):
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
...
тому encrypt
і decrypt
функції, і функції очікують, що ключ буде bytea
. Згідно з повідомленням про помилку, "вам може знадобитися додати явні типи".
Однак він добре працює на Pg 9.1, тому я підозрюю, що в ньому є більше, ніж ви показали. Можливо, у вас є ще одна функція, також названа encrypt
з трьома аргументами?
Ось як це працює на чистому Pg 9.1:
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)
Авоога! Авоога! Основний ризик впливу, необхідна надзвичайна обережність адміністратора!
BTW, будь ласка, подумайте, чи PgCrypto справді правильний вибір. Клавіші ваших запитів можуть виявлятися в pg_stat_activity
системі, а система log_statement
веде журнал через або через криптовиклади, які не вдається помилитися. IMO часто краще робити криптовалюту в додатку .
Побачте цей сеанс, client_min_messages
увімкнено, щоб ви могли бачити, що з’явиться в журналах:
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
можна уникнути, відмінивши доступ до pg_stat_activity
з public
, але це тільки йде , щоб показати , що вона не може бути краще , щоб відправити ваш ключ до БД , якщо ви не знаєте , ваш додаток є єдиним коли - або доступ до нього. Навіть тоді я цього не люблю.
Якщо це паролі, чи варто взагалі зберігати їх?
Крім того, якщо ви зберігаєте паролі, не кодуйте їх двосторонньо; якщо взагалі можливі паролі солі, тоді хешуйте їх і зберігайте результат . Зазвичай вам не потрібно мати можливість відновити прозорий текст пароля, лише підтвердьте, що збережений хеш відповідає паролю, який користувач надсилає вам для входу в систему, коли хешируется з тією ж сіллю.
Якщо це автор, нехай хтось інший зробить це за вас
Ще краще, взагалі не зберігайте пароль, не підтверджуйте автентифікацію проти LDAP, SASL, Active Directory, постачальника OAuth або OpenID або іншої зовнішньої системи, яка вже розроблена і працює.
Ресурси
та багато іншого.