\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 або іншої зовнішньої системи, яка вже розроблена і працює.
Ресурси
та багато іншого.