PostgreSQLでaes-encryptionを使用する方法は?


15

次のステートメントを使用してaes暗号化を試みました。

SELECT encrypt('test', 'key', 'aes');

うまくいきましたが、値を解読できません。それをデータ型byteaのフィールドに挿入しましたが、それが正しい方法であったかどうかはわかりません。

SELECT decrypt(pw, 'key', 'aes') FROM table WHERE ID = 1;

私にエラーを与えます

エラー:関数decrypt(bytea、unknown、unknown)は存在しません
LINE 1:SELECT decrypt(pw、 'key'、 'aes')FROM tabelle WHERE ID = 7; ^
ヒント:指定された名前と引数のタイプに一致する関数はありません。明示的な型キャストを追加する必要がある場合があります。

つまり、encrypt()は既存の関数であり、decrypt()ではないということですか?aesで暗号化された値を他にどのように取得できますか?

回答:


16

\df *cryptpsqlの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
 ...

その両方encryptdecrypt機能キーがあることを期待します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_activitypublic

パスワードの場合、それらを保存する必要がありますか?

さらに、パスワードを保存する場合は、双方向で暗号化しないでください。可能な限りすべてのソルトパスワードがハッシュされ、結果が保存される場合。通常、パスワードのクリアテキストを回復する必要はありません。保存されたハッシュが、同じソルトでハッシュされたときにログインするためにユーザーが送信したパスワードと一致することを確認するだけです。

許可されている場合は、他の人にあなたに代わってもらいましょう

さらに良いことに、パスワードをまったく保存せずに、LDAP、SASL、Active Directory、OAuthまたはOpenIDプロバイダー、または既に設計され動作している他の外部システムに対して認証します。

資源

などなど。


それは私が示した以上のものではなく、新しい関数を定義しませんでした。これは新しくインストールされたpostgresqlです。サンプルと私が投稿した最初の選択ステートメントもその間機能せず、上記の投稿と同じエラーを返すことは非常にいらいらします。どこかで問題が発生しました...とにかく答えてくれてありがとう。
32ビット浮動小数点

CREATEから新しくdデータベースを試してくださいtemplate0。例えばCREATE DATABASE testdb TEMPLATE template0、その後CREATE EXTENSION pgcrypto;、テスト。template1に危険なものがあるかどうかを確認します。
クレイグリンガー

dbの双方向復号化に関する注意。私はそれが常に間違った方向だとは思わないが、それは複雑さを追加し、あなたがこれに対処するどこでもあなたは本当にdbでより複雑になるかもしれないキー管理に対処しなければならない。
ラヴァーズ

また、パスワードを復号化する必要は決してなく、より多くの人が管理するシステムに接続するという考え方は、通常、セキュリティ面で大きな勝利です。
ラヴァーズ

3
笑、「Awooga!Awooga!」の+1
ジェロミーフランス語
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.