\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
、3つの引数を持つ別の関数もありますか?
クリーンな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)
アオウガ!アオウガ!重要な露出のリスク、管理者の極端な注意が必要です!
ところで、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
も可能です。2つのセッションを開きます。
- 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
権限のない攻撃者がそれを使用せずに再現することができます。適切なタイミングをとるのは困難です。経由の攻撃はfrom pg_stat_activity
へのアクセスを取り消すことで回避できますが、アクセスするのはアプリだけであることがわかっていない限り、DBにキーを送信するのが最善ではないことを示すだけです。それでも、私は好きではありません。pg_stat_activity
public
パスワードの場合、それらを保存する必要がありますか?
さらに、パスワードを保存する場合は、双方向で暗号化しないでください。可能な限りすべてのソルトパスワードがハッシュされ、結果が保存される場合。通常、パスワードのクリアテキストを回復する必要はありません。保存されたハッシュが、同じソルトでハッシュされたときにログインするためにユーザーが送信したパスワードと一致することを確認するだけです。
許可されている場合は、他の人にあなたに代わってもらいましょう
さらに良いことに、パスワードをまったく保存せずに、LDAP、SASL、Active Directory、OAuthまたはOpenIDプロバイダー、または既に設計され動作している他の外部システムに対して認証します。
資源
などなど。