gpgキーストアに同じUIDで複数の鍵ペアを登録してしまうと、ファイルにexportした際に1ファイルに複数の鍵情報が入ってしまい、1ファイル1鍵を期待しているpgcryptoに怒られます。
事象
gpgで作った鍵ペアをエクスポートしてpgcryptoで使おうとして発生。cryptoテーブルのpubkeyカラムにはgpgで作った公開鍵をバイナリで入れている状態。
postgres=# select pgp_pub_encrypt('平文', (SELECT pubkey FROM crypto));
ERROR: Several keys given - pgcrypto does not handle keyring
Ascii Armorテキストでデータ登録し直し、dearmorしようとしても以下のエラーが発生。
postgres=# select dearmor((SELECT pubkey FROM crypto));
ERROR: Corrupt ascii-armor
原因
gpgキーストアに同じuidで複数の鍵ペアを登録してしまった為。
gpg –gen-keyを同じ内容で繰り返すとキーストアはこんな状態。
「postgres」 UIDで鍵ペアが重複登録されています。
// 秘密鍵リングの一覧を表示
-bash-4.2$ gpg -K
/var/lib/pgsql/.gnupg/secring.gpg
---------------------------------
sec 2048R/45019AF0 2019-09-23
uid postgres <postgres@localhost>
ssb 2048R/D8BE7B5D 2019-09-23
sec 2048R/224F2773 2019-09-23
uid postgres <postgres@localhost>
ssb 2048R/3E1F48ED 2019-09-23
-k(小文字)オプションで公開鍵リングを見ても同じ状態。
この状態だと「gpg -a -o public.key –export UID」などで吐かれるファイルに複数の鍵情報が入ってしまい、dearmor関数やpg_pub_encrypt関数が正常に動かない。
対処
片方の鍵ペアを削除してexportで1ファイル分の情報しかエクスポートされないようにする。
秘密鍵を一個削除。
-bash-4.2$ gpg --delete-secret-keys postgres
gpg (GnuPG) 2.0.22; Copyright (C) 2013 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
sec 2048R/45019AF0 2019-09-23 postgres <postgres@localhost>
この鍵を鍵リングから削除しますか? (y/N) Y
これは秘密鍵です! 本当に削除しますか? (y/N) Y
公開鍵を一個削除。
-bash-4.2$ gpg --delete-keys postgres
gpg (GnuPG) 2.0.22; Copyright (C) 2013 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
pub 2048R/45019AF0 2019-09-23 postgres <postgres@localhost>
この鍵を鍵リングから削除しますか? (y/N) Y
「postgres」UIDの鍵ペアが1個しかない状態でexportし、PostgreSQLテーブルカラムにインポートするなり、pg_read_file()して使うなりすれば掲題のエラーは回避可能です。
私のようにとっちらかって同じ内容のgpg –gen-keyをしてしまい、上手くエクスポート出来なくなった時はgpg -Kしてみるといいかも知れません。