Linuxコマンド辞典 gpg/gpg2コマンド(セキュリティ)

OpenPGPのGNU実装の暗号化/復号化/署名を利用する「gpg/gpg2」コマンドの概要と使い方を記載しています。

RHEL Fedora CentOS Vine Deblan Ubuntu Plamo

概要・使用方法

書式

$ gpg [オプション] [ファイル名]
$ gpg2 [オプション] [ファイル名]

gpg(Pretty Good Privacy)は、暗号化や署名の規格RFC4880、通称「OpenPGP」のGNUによる実装「GNU Privacy Guard」のコマンドラインツールです。gpgはGnuPGのversion 1シリーズ、gpg2はversion 2のコマンドです。ここでは共通オプションを扱いますが、解説はgpgで行っています。

gpgの主な機能は以下の通りです。Linuxディストリビューションではパッケージの改竄検知などに利用されています。

  • 鍵の管理
  • 暗号化/復号化
  • 電子署名と署名検証

gpgで暗号化したファイルのやり取り、電子署名の検証を行っています。OpenPGPは、共通鍵暗号と公開鍵暗号を利用します。公開鍵暗号を利用するために、最初に自分の鍵ペアを作成する必要があります。鍵を生成する際に、鍵の種類/鍵の長さ/有効期限を指定します。また、鍵所有者情報として本名/メールアドレス/コメント(任意)を入力し鍵のパスフレーズを設定します。鍵を生成する際に、複雑な鍵を生成するためには乱数を貯める必要があります。乱数を貯めるためにキーボードやマウスなどをぐりぐり動かすことが求められます。乱数が貯まれば鍵が生成されます。

オプション

–gen-key公開鍵と秘密鍵の鍵ペアを作成する
–gen-revoke ユーザID指定したユーザID鍵を失効する際に利用する失効証明書を作成する
-k
–list-keys
鍵一覧を出力する
–fingerprint [ユーザID]フィンガープリントを出力する
–delete-key ユーザID公開鍵リストから鍵を削除する
–import鍵をインポートする
–recv-keys ユーザID指定したユーザIDのキーをキーサーバから取得する
–search-keys ユーザIDキーサーバにユーザIDを問い合わせる
-e
–encrypt
ファイルを暗号化する
-c
–symmetric
共通鍵暗号でファイルを暗号化する
-r ユーザID
–recipient ユーザID
指定するユーザの公開鍵を利用する
–passphrase 文字列パスフレーズに指定した文字列を利用する
–passphrase-fd Nパスフレーズを読み込むファイルディスクリプタを指定する。0を指定すると標準入力になる
-d ファイル名
–decrypt ファイル名
ファイルを復号化する
-s
–sign
電子署名を行う
–clearsign ファイル名相手がGPGを持っていなくても読める形式で電子署名のみを付加する
–sign-key 名前指定した名前の公開鍵に署名する
-b ファイル名
–detach-sign ファイル名
指定したファイルの分離署名を作成する
–verify ファイル名電子署名されたファイルを検証する
–export外部ファイルにエクスポートする
-a
–armor
ASCII形式で出力する(デフォルトはOpenPGPバイナリ形式)
-o ファイル名
–output ファイル名
出力ファイルを指定する
–keyserver サーバ名キーサーバを指定する
–send-keys ユーザIDキーサーバに鍵を送る

鍵を生成する

最初にGnuPGの鍵ペアを作成します。秘密鍵を保護するパスフレーズを設定します。鍵の種類の選択が表示された場合は、デフォルト(RSAとRSA)を選択します

$ gpg --gen-key

実行結果

[rin@centos ~]$ gpg --gen-key
gpg (GnuPG) 2.2.20; Copyright (C) 2020 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.

注意: 全機能の鍵生成には "gpg --full-generate-key" を使います。

GnuPGはあなたの鍵を識別するためにユーザIDを構成する必要があります。

本名: test server
電子メール・アドレス: rin@example.jp   #<本名を入力する
次のユーザIDを選択しました:
    "test server <rin@example.jp>"   #<メールアドレスを入力する

名前(N)、電子メール(E)の変更、またはOK(O)か終了(Q)? o  #<入力に間違いがなければo(アルファベットのオー)を入力します
たくさんのランダム・バイトの生成が必要です。キーボードを打つ、マウスを動か
す、ディスクにアクセスするなどの他の操作を素数生成の間に行うことで、乱数生
成器に十分なエントロピーを供給する機会を与えることができます。
たくさんのランダム・バイトの生成が必要です。キーボードを打つ、マウスを動か
す、ディスクにアクセスするなどの他の操作を素数生成の間に行うことで、乱数生
成器に十分なエントロピーを供給する機会を与えることができます。
gpg: /home/rin/.gnupg/trustdb.gpg: 信用データベースができました
gpg: 鍵AA16CC378FC7E371を究極的に信用するよう記録しました
gpg: ディレクトリ'/home/rin/.gnupg/openpgp-revocs.d'が作成されました
gpg: 失効証明書を '/home/rin/.gnupg/openpgp-revocs.d/5331A11AA049B660954658DCAA16CC378FC7E371.rev' に保管しました。
公開鍵と秘密鍵を作成し、署名しました。

pub   rsa2048 2023-01-27 [SC] [有効期限: 2025-01-26]
      5331A11AA049B660954658DCAA16CC378FC7E371
uid                      test server <rin@example.jp>
sub   rsa2048 2023-01-27 [E] [有効期限: 2025-01-26]

[rin@centos ~]$ 

失効証明書を作成する

パスフレーズが漏れてしまったときのために鍵を無効化する失効証明書を作成しておきます。

$ gpg --output ~/.gnupg/revokecert.asc --gen-revoke ユーザID

実行結果

鍵作成で作成した鍵を無効化するために失効署名書を作成しています。

[rin@centos ~]$ gpg --output ~/.gnupg/revokecert.asc --gen-revoke AA16CC378FC7E371

sec  rsa2048/AA16CC378FC7E371 2023-01-27 test server <rin@example.jp>

この鍵に対する失効証明書を作成しますか? (y/N) y #<作成意思を確認する
失効の理由を選択してください:
  0 = 理由は指定されていません
  1 = 鍵(の信頼性)が損なわれています
  2 = 鍵がとりかわっています
  3 = 鍵はもはや使われていません
  Q = キャンセル
(ここではたぶん1を選びたいでしょう)
あなたの決定は? 0                            #<理由を選択します。
予備の説明を入力。空行で終了:
> 
失効理由: 理由は指定されていません
(説明はありません)
よろしいですか? (y/N) y                      #<最終確認
ASCII外装出力を強制します。
失効証明書を作成しました。

みつからないように隠せるような媒体に移してください。もし_悪者_がこの証明書への
アクセスを得ると、あなたの鍵を使えなくすることができます。
媒体が読出し不能になった場合に備えて、この証明書を印刷して保管するのが賢明です。
しかし、ご注意ください。あなたのマシンの印字システムは、他の人がアクセスできる
場所にデータをおくことがあります!
[rin@centos ~]$ 

失効証明書を使って鍵を無効化する

[rin@centos ~]$ gpg --import ~/.gnupg/revokecert.asc
gpg: 鍵AA16CC378FC7E371:"test server <rin@example.jp>"失効証明書をインポートしました
gpg:           処理数の合計: 1
gpg:         新しい鍵の失効: 1
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: 深さ: 0  有効性:   1  署名:   0  信用: 0-, 0q, 0n, 0m, 0f, 1u
gpg: 次回の信用データベース検査は、2025-01-26です
[rin@centos ~]$ 

GnuPGでは共通鍵暗号を使った暗号化もできます。この場合は相手の公開鍵は不要です。

共通鍵を使ってファイルを暗号化する

[rin@centos ~]$ gpg -c test.txt 
[rin@centos ~]$ ls test.txt.gpg 
test.txt.gpg               

共通鍵を使ってファイルを復号する

[rin@centos ~]$ gpg test.txt.gpg

公開鍵暗号を使うには、あらかじめ公開鍵をエクスポートして相手に送っておく必要があります。

公開鍵をpubkeyファイルとしてエクスポートする

[rin@centos ~]$ gpg -o pubkey -a --export rin@example.jp
[rin@centos ~]$ ls pubkey 
pubkey
[rin@centos ~]$ 

公開鍵を受け取った側(暗号化する側)はインポートします。

公開鍵をpubkeyファイルをインポートする

[rin@centos ~]$ gpg --import pubkey
gpg: 鍵AA16CC378FC7E371:"test server <rin@example.jp>"変更なし
gpg:           処理数の合計: 1
gpg:               変更なし: 1
[rin@centos ~]$ 

鍵の一覧を表示する

[rin@centos ~]$  gpg --list-keys
gpg: 信用データベースの検査
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: 深さ: 0  有効性:   1  署名:   0  信用: 0-, 0q, 0n, 0m, 0f, 1u
gpg: 次回の信用データベース検査は、2025-01-26です
/home/rin/.gnupg/pubring.kbx
----------------------------
pub   rsa2048 2023-01-27 [SC] [失効: 2023-01-27]
      5331A11AA049B660954658DCAA16CC378FC7E371
uid           [  失効  ] test server <rin@example.jp>

pub   rsa2048 2023-01-27 [SC] [有効期限: 2025-01-26] #<主公開鍵
      4FB50A98BE22C616895FFB0D741D0EEE34528BF3
uid           [  究極  ] aaaaa <rin@gmail.com>
sub   rsa2048 2023-01-27 [E] [有効期限: 2025-01-26]  #<副公開鍵

送り先のメールアドレス(鍵を識別するID)を指定して暗号化します。暗号化されたファイルは元のファイル名に「.asc」が付きます。

公開鍵でファイルを暗号化する

[rin@centos ~]$ gpg -e -a -r rin@example.jp test.txt

暗号化ファイルを受け取った側は自分のパスフレーズを入力して暗号化します。

公開鍵で暗号化されたファイルを復号する

[rin@centos ~]$ gpg test.txt.asc

キーサーバへ鍵を登録する

OpenPGPはSSL/TLSのように第三者による認証局が存在保証をするわけではありません。鍵が公開されているかとすべて信用して取り込むのではなく、信用できるもの同士鍵の所持証明を行い相互に署名することで「Web of Trust」を構築します。これに参加するためにはまず鍵を作成した後で、その鍵を相手に署名してもらうためにキーサーバに登録します。

$ gpg --keyserver pgp.mit.edu --send-key ユーザID

ユーザコミュニティなどで開催されるキーパーティに参加したり、個人的に会うことで鍵の情報を確認します。確認内容にはメールアドレス、鍵ID、フィンガープリント、有効期限などを確認します。本人確認と鍵確認ができたら、相手の鍵をキーサーバから取得します。

キーサーバからの鍵取得/署名

$gpg --keyserver pgp.mit.edu --recv-keys ユーザID

鍵のフィンガープリントを確認し、間違いなければ署名/確認します。

$gpg --fingerprint <相手の鍵ID> #<フィンガープリントチェック
$gpg --sign-key <相手の鍵ID>    #<相手の鍵への署名
$gpg --check-sigs <相手の鍵ID>  #<署名の確認

次に署名した鍵をファイルに出力し相手にメール送信します。1つの鍵で複数のメールアドレスを登録している場合はそれぞれに送信します。

署名した相手の鍵を出力する

$gpg --export -a 相手の鍵ID > ファイル名

同じように相手も署名してくれた鍵を送付してくるはずです。これを取り込みます。

署名された鍵の取込/キーサーバーへの送信

$gpg --import ファイル名

キーサーバに公開鍵を送信することで、自分の鍵が署名されていることを公開します。

キーサーバに公開鍵を送信する

$gpg --keyserver pgp.nic.ad.jp --send-keys <あなたの鍵ID>
$gpg -keyserver pgp.mit.edu --send-keys <あなたの鍵ID>