# OpenPGP と GnuPG

アリスとボブ

バージョン： 2.1

本ガイドの最終更新： 2023-02-20

RFC 4880 （更新：2020-01-21） | GnuPG 2.2

ガイド一覧に戻る — Markdown | HTML

1. OpenPGP
   1. OpenPGP とは
   2. 概要
2. GnuPG
   1. GnuPG とは
   2. 準備
   3. 使用例
3. 主要概念と使用方法
   1. 公開鍵
   2. 秘密鍵
   3. 鍵管理
   4. メッセージ
   5. 署名
   6. Base64 符号化
   7. 鍵サーバ
   8. 信用
   9. 鍵ストレッチング
4. 注意点と限界
   1. 秘密鍵の守秘は重大
   2. メタデータをほぼ全く保護しない
   3. オプション、対応アルゴリズム、悪特徴、安全でないデフォルト
   4. 脆弱な OpenPGP 対応メールクライアント
   5. 使い難さとミスしやすさ
   6. 鍵署名と信用の輪に関する問題
   7. 鍵サーバを使わない方がいいかも？
   8. 署名の検証と解釈に関する問題
   9. 鍵指紋に関する問題
   10. メールアドレスの公開とメールの使用への圧力
   11. 長期鍵の問題
   12. 公開鍵の大きさ
5. GnuPG コマンド一覧
   1. 鍵操作
   2. メッセージ操作
   3. 信用操作
   4. 他の操作
6. 推奨一覧
   1. GnuPG 環境設定
   2. GnuPG 使用慣行
7. 付録
   1. よく使われるアルゴリズム
   2. よくある署名種類
   3. よくある OpenPGP データのパケット種類
   4. 公開鍵アルゴリズムのサイズと生成時間の比較
   5. 信用の輪の解説

注： OpenPGP 技術仕様の更新が検討されていて、新仕様に対応を始めている GnuPG 2.3 がリリースされました。そのため、本ガイドの一部の内容が将来に古くなります。

注： GnuPG を中心に OpenPGP を説明します。他の OpenPGP クライアントには GnuPG と異なる動作、オプション、デフォルトなどがあります。

# OpenPGP

## OpenPGP とは

OpenPGP （オープン PGP）は、公開鍵暗号方式の技術仕様です。 1991 年に開発された “Pretty Good Privacy” （PGP）というソフトウェアから由来したものです。主に電子メールの暗号化に使われているが、ファイル暗号化、データの完全性検証などという使用事例もあります。

PGP 開発当初の 1991 年、アメリカ連邦政府が暗号を「軍需品」として輸出禁止をしていたが、開発者 Phil Zimmermann は合衆国憲法修正第一条（言論と出版の自由）を創造的に活用することで輸出禁止を法的迂回しました。 PGP のソースコードを書籍1として出版して国外拡散に成功しました。一時的に PGP の国内版と国際版が平行に開発されていたが、 1999 年にアメリカ連邦政府が PGP 輸出を一部の国を除いて認めた後に国際版の開発が終了しました。

→ 外部資料： “Why I Wrote PGP” （1991）： `https://www.philzimmermann.com/EN/essays/WhyIWrotePGP.html`

Zimmermann が暗号に関するオープン標準の重要性を意識したことを契機に、 1997 年、 OpenPGP という技術仕様は Internet Engineering Task Force （IETF）に提案されました。一部の PGP 暗号アルゴリズムにライセンスや特許等の懸念があったため、法的妨害のないアルゴリズムだけを採用した “Unencumbered PGP” という当初の名称があったが、 “OpenPGP” という名称で提案されました。 1998 年に IETF が提案を受け入れ、現在も広く使われています。

現在は RFC 4880 （OpenPGP 主要）、 RFC 5581 （Camellia サイファ）と RFC 6637 （楕円曲線暗号）として存在します。 OpenPGP の技術仕様と関連技術仕様は以下のとおりです。

- PGP：
  - RFC 1991 “PGP Message Exchange Formats” （RFC 4880 により破棄）
- OpenPGP：
  - RFC 2440 “OpenPGP Message Format” （RFC 4880 により破棄）
  - RFC 4880 “OpenPGP Message Format” （現在有効）
  - RFC 5581 “The Camellia Cipher in OpenPGP” （RFC 4880 を更新）
  - RFC 6637 “Elliptic Curve Cryptography (ECC) in OpenPGP” （RFC 4880 を更新）
  - draft-ietf-openpgp-crypto-refresh “OpenPGP Message Format” （草案）
- PGP/MIME2：
  - RFC 2015 “MIME Security with Pretty Good Privacy (PGP)”
  - RFC 3156 “MIME Security with OpenPGP”

## 概要

利用者ができる操作は OpenPGP クライアント次第で、柔軟さを欠けているクライアントがあるが、本セクションでは OpenPGP の特徴を説明します。

暗号技術入門を希望する読者は、以下のガイドを参照してください。

→ ガイド：暗号技術入門 — Markdown | HTML

### 利用者が公開鍵・秘密鍵を自分で保管・管理できる

他の多くの暗号系と異なり、 OpenPGP では利用者が公開鍵・秘密鍵を自分で保管・管理できます。利用者が自由に鍵を生成・追加・編集・削除・共有などをします。鍵の配布は利用者自身または鍵サーバ（keyserver）経由で行われ、他人の公開鍵は自動的に信用されず、利用者自身の判断または信用度計算で信用の可否が決まります。多くの OpenPGP クライアントでは、秘密鍵は利用者のデバイスだけに保管され、セキュリティ向上のためにオフラインデバイスに保管できます。

### ハイブリッド暗号系

OpenPGP はハイブリッド暗号系です。暗号文のセッション鍵は受信者の公開鍵かパスワードで暗号化されます。署名で完全性検証や認証を提供する保管時の暗号化と E2EE （エンドツーエンド暗号化）3を可能にします。

### 多様性と用途の広さ

OpenPGP クライアントは一般的に生成・インポート・削除などの鍵操作機能や暗号化・復号化・署名・検証などの暗号操作機能を提供し、メール暗号化、ファイル暗号化、データの署名・検証などという様々な用途があります。コマンドラインインターフェイス（CLI）やグラフィックユーザインタフェイス（GUI）など様々なインターフェイスのクライアントが存在します。 OpenPGP はオープン標準であるため、誰でも許可やライセンスなどを取得せずに自由に OpenPGP クライアントを実装できます。

### 実装例と使用例

推奨・支持ではなく、徹底的なリストではないが、以下は OpenPGP クライアントの実装例と使用例です。（括弧内はソフトウェアまたは OpenPGP 機能に関する説明）

- GnuPG
  - Linux 類や BSD 類：デフォルトでインストールされている場合が多い
  - Mac： GPGTools
  - Windows： Gpg4Win
- APT （リポジトリ情報の署名）
- Git （ソースコードのコミットやタグなどの署名）
- LibreOffice （ドキュメントの署名・暗号化）
- mutt （CLI メールクライアント）
- OpenKeyChain （鍵を管理する Android アプリ）
- OpenPGP.js （ウェブアプリ用ライブラリ）
- SSH （認証）
- Thunderbird （GUI メールクライアント）

→ 外部資料：メール暗号化ソフトウェア一覧： `https://www.openpgp.org/software/`

→ 外部資料： GnuPG フロントエンド一覧： `https://gnupg.org/software/swlist.html`

# GnuPG

## GnuPG とは

GnuPG （GNU Privacy Guard）は、 PGP の FLOSS 代用として 1997 年に初めてリリースされた OpenPGP 準拠ソフトウェアです。 CLI （コマンドラインインターフェイス）のソフトウェアだが、 GnuPG に対応している様々な GUI フロントエンドも存在します。

GnuPG では自由自在に CLI で暗号化や署名などの操作ができ、利用者に強力な暗号技術と鍵の支配を提供します。

## 準備

### ダウンロード

GnuPG は公式サイトまたはミラーからダウンロードできます。ここで GnuPG 2.3 （本ガイドが扱う 2.2 よりも新しい）や GnuPG 2.2 （本ガイドが扱うバージョン）などのソースコードがダウンロードできます。

`https://gnupg.org/download/index.html`

また、ミラーからもダウンロードできます。以下はミラー一覧ページと一部の HTTPS 対応ミラーです。

`https://gnupg.org/download/mirrors.html`

- DK： `https://mirrors.dotsrc.org/gcrypt/`
- UK： `https://ftp.heanet.ie/mirrors/ftp.gnupg.org/gcrypt`
- UK： `https://www.mirrorservice.org/sites/ftp.gnupg.org/gcrypt`

Linux （特に Debian 系）に既にインストールされている可能性が高いが、そうでない場合に以下のように GnuPG をインストールします。（以下の検証とインストールのサブセクションは該当しません）

    # apt install gnupg

Windows と Mac を対象にした専用ソフトウェアもあります。

- Gpg4Win （Windows）： `https://gpg4win.org`
- GPGTools （macOS）： `https://gpgtools.org`

### 検証

入手した GnuPG が安全で、実際に GnuPG がリリースしたインストールファイルだと検証することが重要です。検証方法は以下の手順で行います。

1. GnuPG 開発者の署名用 PGP 公開鍵を入手する。
2. 公開鍵を（指紋を照合して）検証した上で、インポートする。
3. ダウンロードした GnuPG ファイルを検証する。

以上を入手したら、検証を行います。

公開鍵 `<key-file>` の鍵指紋が正しいことを確認した上で（以下のセクションに記載された検証 URL を参照）、公開鍵を GnuPG の鍵輪に追加します。

    $ gpg --show-key <key-file>
    ... （鍵の情報の表示）
    $ gpg --import <key-file>

公開鍵のインポートが成功したことを確認します。

    $ gpg -k <key>
    ... （鍵の情報の表示）

ダウンロードしたファイル `<file>` （例： `gnupg-2.2.36.tar.bz2`）を署名ファイル `<signature>` （例： `gnupg-2.2.36.tar.bz2.sig`）で検証します。

    $ gpg --verify <signature> <file>

検証コマンドの出力を確認します。 `Good signature from ...` （またはそれに類似した日本語）が表示された場合、入手したファイルが安全な可能性がおそらく高いでしょう。

以下のセクションは各ソフトウェアの署名鍵や検証方法の情報です。

#### GnuPG ソースコード

GnuPG の検証方法と PGP 鍵の入手などについて、 GnuPG の説明ページを参照してください。

→ 外部資料： `https://gnupg.org/download/integrity_check.html`

GnuPG のソフトウェアと署名は以下の URL からダウンロードします。

`https://gnupg.org/download/index.html`

GnuPG 開発者の署名用公開鍵は以下の URL からダウンロードします。

`https://gnupg.org/download/signature_key.html`

#### Gpg4Win

Gpg4Win の検証方法と PGP 鍵の入手などについて、 Gpg4Win の説明ページを参照してください。

→ 外部資料： `https://gpg4win.org/package-integrity.html`

Gpg4Win のソフトウェアと署名は以下の URL からダウンロードします。

`https://gpg4win.org/download.html`

署名鍵は過去に Intevation （`ssl.intevation.de`）にあったが、 2021 年に GnuPG 公式リリース署名鍵が使用されるようになりました。 GnuPG 開発者の署名用公開鍵は以下の URL からダウンロードします。

`https://gnupg.org/download/signature_key.html`

#### GPGTools

GPGTools のソフトウェアと署名は以下の URL からダウンロードします。

`https://gpgtools.org`

GPGTools 開発者の署名用公開鍵は `keys.openpgp.org` 鍵サーバからダウンロードします。ホームページのフッタに GPGTools 署名鍵の鍵指紋が記載されています。

`https://keys.openpgp.org/search?q=85E38F69046B44C1EC9FB07B76D78F0500D026C4`

または

`https://keys.openpgp.org/search?q=team%40gpgtools.org`

### インストール

- Windows：入手・検証した `.exe` ファイルを実行して、手順を踏みます。
- macOS：入手・検証した `.dmg` ファイルを実行して、手順を踏みます。

### 設定

GnuPG のホームディレクトリ（home directory）に以下のデータが保存されます。ホームディレクトリはたいてい `~/.gnupg/` だが、 OS によって異なります。本ガイドではホームディレクトリを `<GNUPGHOME>` と示します。

- 鍵輪（keyring）：公開鍵のデータベース（`pubring.kbx`）
- 秘密鍵（`private-keys-v1.d/*.key`）
- 失効証明書（`openpgp-revocs.d/*.rev`）
- 信用データベース（`trustdb.gpg`）
- 環境設定ファイル（`*.conf`）

ホームディレクトリが存在しない場合、 GnuPG を実行することで新規ホームディレクトリを作成・表示します。以下に、ホームディレクトリがなかった場合の実行結果です。

    $ gpg --list-keys --list-options show-keyring | head -n 1
    gpg: directory '/home/（ユーザ名）/.gnupg' created
    gpg: keybox '/home/（ユーザ名）/.gnupg/pubring.kbx' created
    gpg: /home/（ユーザ名）/.gnupg/trustdb.gpg: trustdb created

ホームディレクトリの存在またはパスが不明な場合、同じようにホームディレクトリを確認します。ホームディレクトリが存在する場合、パスが表示されます。

    $ gpg --list-keys --list-options show-keyring | head -n 1
    /home/（ユーザ名）/.gnupg/pubring.kbx

ホームディレクトリが既に存在している場合、（他人の GnuPG データでない限り）それを消去してから新規ホームディレクトリを作成します。

GnuPG を使用する前に、自分に適した環境設定ファイルを用意して設置することを推奨します。新規ホームディレクトリが出来上がったら、用意した環境設定ファイルをホームディレクトリに置きます。

## 使用例

注：例に現れるメッセージ、署名、鍵、チェックサムなどは捏ち上げたため、検証しようとしても失敗します。

本セクションでは GnuPG の使用例を紹介します。

### ファイルとチェックサムの保護

検証セクションでは既にソフトウェア検証を説明しました。署名されたファイル、分離署名と署名鍵を入手した場合、以下のように検証を行います。

Bob からファイルと分離署名を受信した場合、以下のように以下のように検証します。署名日時が期待どおりで Bob からの署名が期待されていた場合、信用されている鍵による `Good signature` （正しい署名）と確認されたため、署名検証が成立します。

    $ gpg --list-keys bob
    /home/alice/.gnupg/pubring.kbx
    --------------------------------
    pub   ed25519/81CD4491E6EE23F8 2021-06-03 [C] [expires: 2023-06-03]
          Key fingerprint = 105A 943C 25D3 9266 8C93  1600 81CD 4491 E6EE 23F8
    uid                 [  full  ] Bob
    sub   ed25519/E4A5866062C8604B 2021-06-03 [S] [expires: 2023-06-03]
          Key fingerprint = 7D0A 1DEE B487 7809 22B3  3054 E4A5 8660 62C8 604B
    sub   cv25519/7FEDDC78489B9C25 2021-06-03 [E] [expires: 2023-06-03]
          Key fingerprint = 7E19 7FC6 B31D 156D 290C  5A42 7FED DC78 489B 9C25
    $ ls
    file0  file0.sig
    $ gpg --verify file0.sig file0
    gpg: Signature made Fri 24 Jun 2022 10:35:50 AM UTC
    gpg:                using EDDSA key 7D0A1DEEB487780922B33054E4A5866062C8604B
    gpg: Good signature from "Bob" [  full  ]
    Primary key fingerprint: 105A 943C 25D3 9266 8C93  1600 81CD 4491 E6EE 23F8
         Subkey fingerprint: 7D0A 1DEE B487 7809 22B3  3054 E4A5 8660 62C8 604B

しかし、ファイルへの直接署名でなく、ファイルのチェックサムに署名する開発者もいます。その場合、チェックサムファイルを署名で検証してから、入手したファイルのチェックサムを手動で照合します。以下の流れは SHA-256 `sha256sum` を前提にするが、他のハッシュ関数にも適用できます。

    $ ls
    file0  file2  SHA256SUMS  SHA256SUMS.sig
    $ gpg --verify SHA256SUMS.sig SHA256SUMS
    gpg: Signature made Tue 28 Jun 2022 08:11:09 AM UTC
    gpg:                using EDDSA key 7D0A1DEEB487780922B33054E4A5866062C8604B
    gpg: Good signature from "Bob" [  full  ]
    Primary key fingerprint: 105A 943C 25D3 9266 8C93  1600 81CD 4491 E6EE 23F8
         Subkey fingerprint: 7D0A 1DEE B487 7809 22B3  3054 E4A5 8660 62C8 604B
    $ cat SHA256SUMS | grep '  file0$'
    5a279dce0322aafa2ded5fbd71ce94385f499e571eab20ecc78e3b3160e69de3  file0
    $ sha256sum file0
    5a279dce0322aafa2ded5fbd71ce94385f499e571eab20ecc78e3b3160e69de3  file0

また、入手したファイルがチェックサムファイルのとおりのディレクトリ構造と一致している場合、全ての入手したファイルを一括して自動的に照合できます。全ての入手したファイルに対して `OK` と表示されたら、検証が成功したということです。 `FAILED` などのチェックサム不一致またはエラーが発生したら、検証が失敗したかもしれません。以下の例では、 `file0` と `file2` の検証が成功したが、 `SHA256SUMS` に記載された `file1` が見つからなかったためエラーが出ました。

    $ sha256sum --check SHA256SUMS
    file0: OK
    sha256sum: file1: No such file or directory
    file1: FAILED open or read
    file2: OK
    sha256sum: WARNING: 1 listed file could not be read

後で検証を行ったり他人に検証してもらったりするために、誰でもがチェックサムを生成したりファイルに署名したりできます。

    $ find . -type f -print
    ./fruits/apple
    ./fruits/banana
    ./vegetables/carrot
    ./vegetables/daikon
    ./vegetables/eggplant
    $ find . -type f -print | grep -v SHA256SUMS \
    >   | xargs -r sha256sum > SHA256SUMS
    $ gpg --detach-sign -u alice SHA256SUMS
    $ find . -type f -print
    ./fruits/apple
    ./fruits/banana
    ./SHA256SUMS
    ./SHA256SUMS.sig
    ./vegetables/carrot
    ./vegetables/daikon
    ./vegetables/eggplant
    $ gpg --verify SHA256SUMS.sig SHA256SUMS
    gpg: Signature made Tue 05 Jul 2022 09:51:22 PM UTC
    gpg:                using EDDSA key 040F3145FCB028003A73B19DCFABC5032E9CC2E8
    gpg: Good signature from "Alice" [ultimate]
    Primary key fingerprint: A7E6 0E7C 26F1 4BBC 69E0  D382 7633 46CA 665E B5CF
         Subkey fingerprint: 040F 3145 FCB0 2800 3A73  B19D CFAB C503 2E9C C2E8
    $ sha256sum -c SHA256SUMS
    ./fruits/apple: OK
    ./fruits/banana: OK
    ./vegetables/carrot: OK
    ./vegetables/daikon: OK
    ./vegetables/eggplant: OK

### 暗号での通信保護

公開予定の平文メッセージに署名して掲示板などに投稿したい場合、クリア署名で実現できます。公開の議論や共同作業において、重要な情報を保護することに役立ちます。例文が公開されたら、誰でもメッセージ “Hello world!” が見えるが、署名が base64 符号化されたためテキストの通信経路上でも配布でき、 Alice の公開鍵を持っている人は署名でメッセージ（と署名者や署名日時などのメタデータ）を検証できます。ただし、一回メッセージに署名して投稿すると、永遠にそのメッセージを否認不可になるので注意してください。また、投稿者と執筆者が OpenPGP 署名で保護されず、署名者と投稿者と執筆者が同じという保証はありません。

    $ echo 'Hello world!' | gpg --clear-sign -u alice
    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA512

    Hello world!
    -----BEGIN PGP SIGNATURE-----

    4ePvSxAe7vAIz1eM7Cpf50dPN/XKXw43sxcjd0aKM+clw98LuPVIrr0o4XNot6B1
    WwgmS6hMakPcdOR6w1gNUEFzI37islEJMVdEZOp8g77BPewRIGKFj7OOF7L6Kv6N
    ZUtN8Ok53i1ritOTiSAdwByH/7hSaKQTBJkU5uT5g87HDNilwPQf8+MMCjigwQ==
    =nyG7
    -----END PGP SIGNATURE-----
    $ echo '（上の暗号文のコピペ）' | gpg --verify
    gpg: Signature made Wed 06 Jul 2022 11:50:00 PM UTC
    gpg:                using EDDSA key 040F3145FCB028003A73B19DCFABC5032E9CC2E8
    gpg: Good signature from "Alice" [ultimate]
    Primary key fingerprint: A7E6 0E7C 26F1 4BBC 69E0  D382 7633 46CA 665E B5CF
         Subkey fingerprint: 040F 3145 FCB0 2800 3A73  B19D CFAB C503 2E9C C2E8

仮に完全性、認証または秘匿性が欠けている通信経路上で通信内容の完全性、認証と秘匿性を保護した通信を実現するために、 OpenPGP で相手宛に暗号化・署名されたメッセージを作成できます。以下のように GnuPG で Bob （と Alice 自身）宛に暗号化されたメッセージを生成できます。 `-sea` は `--sign` （標準署名）、 `--encrypt` （公開鍵暗号化）と `--armor` （base64 符号化）の略です。暗号文を base64 符号化することで、テキストにしか対応していない通信経路上（電子メール、メッセンジャーなど）でも送信できます。ただし、メッセージ関連が否認不可で、 OpenPGP は下部の通信プロトコルを保護できないため署名者と暗号化者と送信者と執筆者が同じという保証はありません。

以下の例は Alice がファイル `activity-plan` に署名して Bob （と Alice 自身）に暗号化する場合のコマンドです。暗号文を生成した後、 `-d` （`--decrypt` の略）で復号化して、平文の出力を捨てて検証します。

    $ gpg -sea --throw-keyids -u alice -r bob -r alice \
    >   activity-plan > ciphertext
    $ cat ciphertext
    -----BEGIN PGP MESSAGE-----

    eVYKv/BEJnEwDY9Q25fuEQIyYYcjqHArOUH301Lc9JJpJdAZjoHg3o/oZofRr314
    575Tm0CCXCNwM1Qx+j2keze3VL3Qde8duTzSZs8JjWY1qIuyh2hTkGObLZZuEMpP
    ZH05hm1qxKKcMjxra8nZOUO56G/rOfd3o8Gp/SQPg746Zsrn2k6eKtEL4TEeUFyE
    Sr4HuxpKtS8ctBt82i7bgGFFl1omr4qRTvaM68DuyWpLtIQxL0UY6VJkNCM1pFff
    GBz3Waa+lKi4R1U8KoIEEaFWEqy04MPjplmj7zvLQRyp5JQT9RmHhg/cTIHhIvRR
    KwebVyXnWAjN0uICcXeM9NenA9HDfJQtVispTIwgyolOQgET/0pWk1ilo8M5K8e2
    CYgJWuOCMxTvwzKoMW7L4WR221HCmB1ouwFFJkH6cllQzqP49RydDF66Rnsvu/yz
    UBXI05EHaNAlLEc7RMU7r+m0QiZ3j40W/2penc5okir39gZpOYa/PgIbFNh+q+PR
    A66o3JdIbcdFI8Z2NYvfC4G/6ag7DkgAJIxYLj2XV4pLZulq+j8EPlMQ26fh2XFB
    368BJ3spUamFN+BtSp9q38HFQLc/tN2gvG+syYJo8Tp4Gld+MouNy+lDFO2RDDCF
    l60BTOBtX1TCvsNr2fRqqBRuRcGCiuwDKh2R7q6fJR9+0JlUSewQA1r4Gr7Jz+Ze
    w8fqPiCL2XgIpGWJ110=
    =Prxj
    -----END PGP MESSAGE-----
    $ cat ciphertext | gpg -d > /dev/null
    gpg: Signature made Wed 06 Jul 2022 00:10:33 AM UTC
    gpg:                using EDDSA key 040F3145FCB028003A73B19DCFABC5032E9CC2E8
    gpg: Good signature from "Alice" [ultimate]
    Primary key fingerprint: A7E6 0E7C 26F1 4BBC 69E0  D382 7633 46CA 665E B5CF
         Subkey fingerprint: 040F 3145 FCB0 2800 3A73  B19D CFAB C503 2E9C C2E8

### ファイルバックアップの保護

個人ファイルのバックアップ保護にも OpenPGP を活用できます。以下のようにディレクトリ構造を一括して暗号化・署名してから、複数の記憶装置に分割できます。 Alice のホームディレクトリ `/home/alice` をバックアップの対象に tarball を作成し、公開鍵暗号化とパスワード暗号化の両方で暗号化し、暗号文を base64 符号化せずに複数のバイナリファイルに保存します。 Alice が各ファイルを個別の記憶装置に移動させることができます。

    $ tar -c --directory=/home/alice . \
    >   | gpg -sec -u alice -r alice \
    >   | split --bytes=4G 'alice-file-backup.'
    $ ls -l --time-style=iso
    -rw-r--r-- 1 alice alice 4294967296 07-15 01:58 alice-file-backup.aa
    -rw-r--r-- 1 alice alice 4294967296 07-15 02:07 alice-file-backup.ab
    -rw-r--r-- 1 alice alice 4294967296 07-15 02:15 alice-file-backup.ac
    -rw-r--r-- 1 alice alice 1930005125 07-15 02:17 alice-file-backup.ad

万が一バックアップからファイルを復元する必要があった場合、各分割ファイルを一つのデバイスにコピーし、逆操作を行います。

注：これは GnuPG や他のコマンドを見せるための仮の使用例です。このような例を実際に実行する前に、ファイル損失などの問題を防ぐよう、コマンドを確認したり効果を理解したりした上で実行してください。

    $ cat alice-file-backup.a[a-d] | gpg -d > /dev/null
    gpg: Signature made Fri 15 Jul 2022 02:17:03 AM UTC
    gpg:                using EDDSA key 040F3145FCB028003A73B19DCFABC5032E9CC2E8
    gpg: Good signature from "Alice" [ultimate]
    Primary key fingerprint: A7E6 0E7C 26F1 4BBC 69E0  D382 7633 46CA 665E B5CF
         Subkey fingerprint: 040F 3145 FCB0 2800 3A73  B19D CFAB C503 2E9C C2E8
    $ cat alice-file-backup.[a-d] | gpg -d \
    >   | tar -x --directory=/home/alice

# 主要概念と使用方法

GnuPG の習得は困難だが、本セクションが出発点になることを目指します。詳しくは以下の資料を参照してください。

- manpage： `man gpg`
- ウェブサイト上のドキュメンテーション： `https://gnupg.org/documentation/index.html`

また、古いが GnuPG についての日本語資料もあります。

→ 外部資料： GNU Privacy Guard 講座： `https://gnupg.hclippr.com/main/index.html`

## 公開鍵

注： OpenPGP においての「公開鍵」（証明書）は本来の「公開鍵」（主鍵や副鍵の鍵データ）と衝突し、実際には証明書を指すため、少し残念な用語です。

OpenPGP においての公開鍵（public key）は、鍵データ（key material、 厳密な意味での公開鍵）、所有者情報、作成日時、有効期限などの情報で構成される証明書（certificate）です。

公開鍵の中に以下の鍵データがあります。

- 主鍵（primary key）：証明書の身元役を果たす鍵。
- 副鍵（subkey）：署名、暗号化などに使われる鍵。

以下の GnuPG コマンドで鍵輪内の公開鍵を表示させます。

    $ gpg --list-keys [<key>]

公開鍵を表示させると以下のような出力を得ます。 `pub` （主鍵）、 `uid` （UID）と `sub` （副鍵）という識別子でそれぞれのデータが識別できます。公開鍵アルゴリズム、鍵指紋、生成日時、有効期限、鍵機能と鍵信用も以下に表示されています。以下の例は主鍵と 2 つの副鍵を含む公開鍵です。

    pub   ed25519/763346CA665EB5CF 2022-05-31 [C] [expires: 2023-05-31]
          Key fingerprint = A7E6 0E7C 26F1 4BBC 69E0  D382 7633 46CA 665E B5CF
    uid                 [ultimate] Alice
    sub   cv25519/DAD46EDC281F5DC8 2022-05-31 [E] [expires: 2023-05-31]
          Key fingerprint = 2882 3E91 EF7C 3C48 5043  FA87 DAD4 6EDC 281F 5DC8
    sub   ed25519/CFABC5032E9CC2E8 2022-05-31 [S] [expires: 2023-05-31]
          Key fingerprint = 040F 3145 FCB0 2800 3A73  B19D CFAB C503 2E9C C2E8

より具体的には、公開鍵には以下の情報が入っています。ただし、以下のリストは公開鍵の実際の構造を表しません。

- 1 つの主鍵（primary key）と 0 つ以上の副鍵（subkey）：
  - 公開鍵アルゴリズム
  - 鍵データ
  - 鍵指紋
  - 鍵機能
  - 生成日時（秒単位）
  - 有効期限（秒単位）
- 1 つ以上の UID
  - 1 つの優先特徴リスト
- OpenPGP バージョン（現在の最新バージョンは 4）
- 主鍵と副鍵を結びつける自己署名

場合によって以下の情報も入っているかもしれません。

- 他の鍵による鍵署名
- 失効署名

この情報の多くは署名で公開鍵（主鍵）に結びつけられます。そのため、データ破損と改竄を検出可能にし、公開鍵を入手した誰でもが公開鍵の内容を検証できます。

公開鍵の情報の多くは編集可能です。

    $ gpg --edit-key [--expert] <key>

しかし、一部の編集をした後に署名が追加されるかもしれず、編集前の情報が上書き（削除）されるとは限りません。編集前の情報を削除するには、編集コマンドの `minimize` サブコマンドで削除できるかもしれません。一部の情報（例えば生成日時）を通常編集できません。

### 鍵指紋と鍵 ID

注：デジタルセキュリティ問題の一種を指す「指紋抽出」もあるため、「鍵指紋」は誤解と不愉快を招くおそれがあり、少し残念な用語です。

鍵指紋（key fingerprint）は、公開鍵から計算される固定長の数値で、公開鍵の識別子として使われます。鍵共有や他の鍵操作を行う際、 OpenPGP 利用者が鍵指紋で公開鍵を照合・指定します。他人の公開鍵を入手する歳、公開鍵所有者から安全な手段で鍵指紋を入手して、入手した鍵の鍵指紋と照合することでその公開鍵を検証することが重要です。

鍵指紋は（SHA-1 ハッシュ関数の出力の） 160 ビット数値で、 16 進数で表すと以下のような 40 文字です。公開鍵の鍵データ（key material）、生成日付などの情報から鍵指紋が計算されます。以下のように空白が挿入されて表示されることが多いが、空白はあくまでも人間がより簡単に読み取れるために挿入されるだけで、空白の有無は自由です。

    A7E6 0E7C 26F1 4BBC 69E0  D382 7633 46CA 665E B5CF

鍵の指定には少し長いため、鍵指紋の後尾の 64 ビット（16 文字）という鍵 ID （key ID）だけで鍵が指定される場合が多いです。例えば、上の鍵指紋に該当する鍵 ID は `763346CA665EB5CF` です。ただし、鍵 ID だけで入手した公開鍵を検証しては不十分です。

### 鍵機能

鍵を生成する際、鍵の機能 （usage、 capability）を指定できます。ただし、鍵署名（certify）の機能は副鍵に与えられず、主鍵は鍵署名の機能を必ず与えられます。

記号^\1*^ | 識別子*2 | 英語 | 機能 | 公開鍵 / 秘密鍵
--- | --- | --- | --- | ---
C | `cert` | certify | 鍵署名 | 署名検証 / 署名生成
E | `encr` | encrypt | 暗号化 | 暗号化 / 復号化
S | `sign` | sign | メッセージ署名 | 署名検証 / 署名生成
A | `auth` | authenticate | 認証 | 身元検証 / 身元証明

- *1： 鍵を表示する際、生成日時の後の括弧内に表示される。
- *2： `--quick-gen-key` などの鍵生成・鍵追加コマンドに使用。

鍵に複数の機能（例えば鍵署名とメッセージ署名）を与えることができます。しかし、主鍵に鍵署名以外の機能を与えず、各機能を一つの有効な鍵だけに与えることを推奨します。主鍵に鍵署名以外の機能（例えばメッセージ署名）も与えた場合、その機能を使えなくならずに主鍵の秘密鍵をオフライン保管できません。一方、ある機能が複数の有効な鍵に付いている場合、その機能を使用する際にどちらの鍵が使われるかがわからなくなります。

### UID

UID （user ID、ユーザ ID）は、鍵の所有者情報を表す UTF-8 文字列です。公開鍵は必ず一つ以上の UID を有します。公開鍵を表示する際、 UID も表示されます。また、 GnuPG では、鍵を指定する際、鍵指紋または鍵 ID でなく UID の内容で指定できます。

よくある UID 形式は以下のように氏名やメールアドレスを含むパターンです。

    氏名 (コメント) <メールアドレス>

とはいえ、 OpenPGP では UID の形式が自由で、実名やメールアドレスを指定しなくても大丈夫です。鍵生成の際、 GnuPG は氏名、メールアドレスとコメントを入力するよう求めるが、希望の UID を氏名として入力し、メールアドレスとコメントを空白にすることで、希望の UID を指定できます。ただし、自由な UID を扱いたい場合、 `--allow-freeform-uid` オプションが必要かもしれません。

UID にコメントを追加すべきでないという主張があります。 UID は他人に証明できる事実だけであるべきという理想かもしれず、コメントは一般的に意味・解釈が不明または非事実の内容です。例えば、 `Alice (offline key) <alice@example.org>` の場合、鍵所有者は名前とメールアドレスを他人に証明できるかもしれないが、 `offline key` （オフライン鍵）を事実として他人に証明できません。それにしても、コメントは鍵の区別や指定に役立つため、必要に応じてコメントを有意義に追加したらいいかもしれません。例えば、 UID に共通内容のある複数の鍵を持っている場合、各鍵に区別用コメントを含む UID を自分の鍵に追加したら各鍵を指定しやすくなります。

    $ gpg --list-keys Alice | grep '^uid'
    uid                 [ expired] Alice (alice2018) <alice@example.org>
    uid                 [ unknown] Alice Smith <asmith@example.net>
    uid                 [ultimate] Alice (alice2021) <alice@example.org>

    $ gpg --list-keys alice2021 | grep '^uid'  # コメントで鍵を簡単に指定できます
    uid                 [ultimate] Alice (alice2021) <alice@example.org>

しかし、一部の OpenPGP クライアント（特にメールクライアント）は以上のような氏名とメールアドレスの UID 形式を強制し、生成時にその形式を強制したりその形式を持たない UID を公開鍵インポート時に拒否したりします。また、コメントは UID の受け入れの妨げになるかもしれません。そのため、 UID を選ぶ際にこのポイントに注意してください。

顔写真や他のデータを持つ拡張 UID （厳密には “user attribute” と呼ばれます）があるが、一般的にはこのような拡張 UID を使用しないことを推奨します。

### 優先特徴リスト

優先特徴リスト（preference list）は、公開鍵（厳密には UID）が優先するサイファ、ハッシュ関数、圧縮関数などの特徴のリストです。公開鍵を扱う送信クライアントは全ての受信者の公開鍵に指定されている優先特徴リストを考慮し、適切なアルゴリズムを選びます。

OpenPGP クライアントが全アルゴリズムに対応しているわけではないため、送信クライアントが受信公開鍵の全優先特徴リストの共通集合を取ってから適切なアルゴリズムを選ぶ必要があります。全優先特徴リストの共通集合が空集合とならないよう、 3DES サイファ（`3DES`）、 SHA-1 ハッシュ関数（`SHA1`）と無圧縮（`Uncompressed`）が優先特徴リストに指定されていなければ、 OpenPGP クライアントはこれらを最後の優先項目として扱います。

自分のクライアントが以下のアルゴリズムに対応していない場合を除き、以下の優先特徴リストをデフォルトとして指定することを推奨します。広く使われていて、 Tails OS 内 GnuPG のデフォルトのリストです。この優先特徴リストをデフォルトにしたら、今後鍵ペアを生成する時にこの優先特徴リストが公開鍵にコピーされます。他の優先特徴リストを指定したら、 OpenPGP クライアントに対する指紋抽出の手がかりになるため注意してください。

特徴 | 鍵編集表示*1 | 推奨値（鍵編集時）*2 | 推奨値（環境設定時）*3
--- | --- | --- | ---
優先サイファ | `Cipher` | `S9 S8 S7 S3` | `AES256 AES192 AES CAST5`
優先ハッシュ関数 | `Digest` | `H10 H9 H8 H11` | `SHA512 SHA384 SHA256 SHA224`
優先圧縮関数 | `Compression` | `Z2 Z3 Z1 Z0` | `ZLIB BZIP2 ZIP Uncompressed`

- *1： `--edit-key` コマンド内の `showpref` サブコマンドで表示される。
- *2： `--edit-key` コマンド内の `setpref` サブコマンドに使用。
- *3： `--default-preference-list` コマンドに使用。

以上の推奨値を優先特徴リストのデフォルトとして設定するには、環境設定ファイル `gpg.conf` に以下の行を追加します。

    default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed

既存の公開鍵に優先特徴リストを推奨値に設定するには、 `--edit-key` コマンドを実行し、 `setpref S9 S8 S7 S3 H10 H9 H8 H11 Z2 Z3 Z1 Z0` サブコマンドを実行します。

    $ gpg --edit-key alice
    Secret key is available.

    sec  ed25519/763346CA665EB5CF
         created: 2022-05-31  expires: 2023-05-31  usage: C
         validity: ultimate
    ssb  cv25519/DAD46EDC281F5DC8
         created: 2022-05-31  expires: 2023-05-31  usage: E
    ssb  ed25519/CFABC5032E9CC2E8
         created: 2022-05-31  expires: 2023-05-31  usage: S
    [ultimate] (1). Alice

    gpg> setpref S9 S8 S7 S3 H10 H9 H8 H11 Z2 Z3 Z1 Z0
    Set preference list to:
         Cipher: AES256, AES192, AES, CAST5, 3DES
         Digest: SHA512, SHA384, SHA256, SHA224, SHA1
         Compression: ZLIB, BZIP2, ZIP, Uncompressed
         Features: MDC, Keyserver no-modify
    Really update the preferences for the selected user IDs? (y/N) y

## 秘密鍵

注： GnuPG 2.2 以前は異なる秘密鍵保存形式を用いました。 GnuPG 2.2 以前から GnuPG 2.2 に秘密鍵を移行するにはエクスポートしてインポートしなおすことが必要かもしれません。

注： GnuPG 2.3 から新しい秘密鍵保存形式が採用される見通しです。本ガイドの一部の内容が将来に古くなる可能性があります。

秘密鍵（private key または secret key）は公開鍵の鍵データに該当する秘密の鍵データで、公開鍵と合わせると鍵ペアを構成します。

以下の GnuPG コマンドで秘密鍵を表示させます。

    $ gpg [--with-keygrip] --list-secret-keys [<key>]

秘密鍵を表示させると以下のような出力を得ます。 `sec` （主鍵）または `ssb` （副鍵）の後に `#` （見つからない）または `>` （スマートカードに保管）が付いている場合、秘密鍵が GnuPG ディレクトリ内に存在しないため使用できません。例えば、主鍵の秘密鍵をオフラインデバイスに保管されている場合、 `sec#` と表示され、鍵署名やほとんどの鍵編集操作ができません。

    sec#  ed25519/763346CA665EB5CF 2022-05-31 [C] [expires: 2023-05-31]
          Key fingerprint = A7E6 0E7C 26F1 4BBC 69E0  D382 7633 46CA 665E B5CF
    uid                 [ultimate] Alice
    ssb   cv25519/DAD46EDC281F5DC8 2022-05-31 [E] [expires: 2023-05-31]
          Key fingerprint = 2882 3E91 EF7C 3C48 5043  FA87 DAD4 6EDC 281F 5DC8
    ssb   ed25519/CFABC5032E9CC2E8 2022-05-31 [S] [expires: 2023-05-31]
          Key fingerprint = 040F 3145 FCB0 2800 3A73  B19D CFAB C503 2E9C C2E8

オプション `--with-keygrip` で秘密鍵の鍵グリップ（keygrip）も表示させます。鍵グリップは GnuPG 内部の秘密鍵の識別子で、 `<GNUPGHOME>/private-keys-v1.d/<keygrip>.key` のように秘密鍵のファイル名が鍵グリップに対応します。

しかし、これは GnuPG 独自の保存形式であることに注意してください。他の OpenPGP クライアントに秘密鍵をエクスポートするには、 `--export-secret-keys` または `--export-secret-subkeys` コマンドを使用する必要があります。すると、公開鍵に似ている OpenPGP データを得ます。

デバイス・クライアント移行またはバックアップの場合以外に秘密鍵をエクスポートする必要がほとんどなく、もちろん秘密鍵を配布すべきではなく、秘密鍵を独占的かつ安全に保管して守るべきです。

## 鍵管理

### 生成

OpenPGP といえば、まずは鍵生成です。 GnuPG では以下のように鍵を生成します。オプション `--expert` は鍵生成オプションをもっと表示させるためです。

鍵生成の際、まずは希望の公開鍵アルゴリズム系が聞かれます。一般的には安全で広く使われている RSA または ECC （楕円曲線）を推奨します。 RSA の方が広く使われているが、鍵サイズが大きく、生成する署名も大きく、公開鍵操作が遅いため、読者自身と相手が使用できれば ECC を推奨します。

    $ gpg --full-gen-key --expert
    Please select what kind of key you want:
    （中略）
       (8) RSA (set your own capabilities)
    （中略）
      (11) ECC (set your own capabilities)
    （中略）
    Your selection? 11

次に主鍵の鍵機能を設定します。主鍵には鍵署名 “Certify” だけにすることを推奨します。後で他の機能を持つ副鍵を追加できます。

    Possible actions for a ECDSA/EdDSA key: Sign Certify Authenticate
    Current allowed actions: Sign Certify

       (S) Toggle the sign capability
       (A) Toggle the authenticate capability
       (Q) Finished

    Your selection? s
    （中略）
    Your selection? q

次に公開鍵アルゴリズムの詳細を指定します。 RSA の場合、鍵サイズ（ビット数）が聞かれます。 ECC の場合、以下のような流れです。 ECC のうち Curve25519・Ed25519 を推奨します。特に、 NIST 曲線はバックドアされたと疑われているため避けてください。

    Please select which elliptic curve you want:
       (1) Curve 25519
    （中略）
    Your selection? 1

次に有効期限を指定します。有効期間（`1y` と `6m` はそれぞれ 1 年間と 6 ヶ月）や期限切れの日（例えば `2024-01-01`）を指定できます。 OpenPGP に前方秘匿性が無く、鍵はいつか危殆化する可能性が否定できないため、デフォルトである無期限をそのままにすることを避けて、 1 年間から 5 年間程度の有効期限を指定することを推奨します。どうしても有効期限が過ぎてもある公開鍵を使い続けたい場合、主鍵の秘密鍵を持っていればいつでも有効期限を延ばすことができます。

    Please specify how long the key should be valid.
    （中略）
    Key is valid for? (0) 1y
    Key expires at Tue 04 Jul 2023 00:00:00 AM UTC
    Is this correct? (y/N) y

次に UID を入力します。オプション `--allow-freeform-uid` が効いている場合、 “Real name” の欄に自由な文字列を入力して他の欄を空白にできます。 OpenPGP メールに利用する場合などにメールアドレスを指定すればいいが、実名やメールアドレスを入れる必要はありません。

    GnuPG needs to construct a user ID to identify your key.

    Real name: Alice
    Email address:
    Comment:
    You selected this USER-ID:
        "Alice"

    Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o

最後にパスワードを指定します。もちろん、強力なパスワードを使用すべきです。パスワードを指定した後、 GnuPG は鍵データを生成し、終了します。

鍵生成が成功したら、以下のデータが保存されます。

- 公開鍵：鍵輪 `<GNUPGHOME>/pubring.kbx` に追加される
- 秘密鍵： `<GNUPGHOME>/private-keys-v1.d/` に追加される
- 失効証明書： `<GNUPGHOME>/openpgp-revocs.d/` に追加される

失効証明書は鍵生成と同時にホームディレクトリに自動生成されるが、失効証明書をオフライン保存に移動させることを推奨します。

鍵生成が成功したら、公開鍵に主鍵と一つの UID しか存在しません。鍵編集コマンドで副鍵や UID を追加します。

鍵生成と鍵編集を終了後、使用事例とデバイスセキュリティ次第だが、主鍵の秘密鍵もオフライン保存に移動させた方がいいかもしれません。

### 編集

自分の鍵または他人の公開鍵を編集する必要が出てくるでしょう。鍵編集では例えば以下の操作ができます。

- 秘密鍵のパスワードの変更
- 優先特徴リストの変更
- 有効期限の変更
- 公開鍵の最小化（最新の自己署名以外の鍵署名の削除）
- 副鍵の追加・削除・失効
- UID の追加・削除・失効
- 鍵全体の失効
- 鍵の無効化・有効化
- 所有者信用の変更

初心者に必要不可欠なサブコマンドは以下です。

- `help`：サブコマンドの一覧を表示
- `list`：編集対象の鍵情報を表示
- `save`：編集を保存して終了
- `quit`：編集を保存せずに終了

例えば、副鍵を追加するには以下の流れで行います。

    $ gpg --edit-key [--expert] <key>
    gpg> addkey
    （中略）
    gpg> save

### インポートとエクスポート

他人と公開鍵を交換したりバックアップを行ったりするには、公開鍵や秘密鍵のインポートとエクスポートが必要です。

- 鍵輪にインポート： `--import`
- 鍵輪からエクスポート：
  - 公開鍵： `--export [--armor]`
  - 秘密鍵（主鍵と副鍵）： `--export-secret-keys [--armor]`
  - 秘密鍵（副鍵）： `--export-secret-subkeys [--armor]`

鍵をインポートする前に、鍵を確認したい場合があるでしょう。

    $ gpg --show-key alice.asc
    pub   ed25519/763346CA665EB5CF 2022-05-31 [C] [expires: 2023-05-31]
          Key fingerprint = A7E6 0E7C 26F1 4BBC 69E0  D382 7633 46CA 665E B5CF
    uid                            Alice
    sub   cv25519/DAD46EDC281F5DC8 2022-05-31 [E] [expires: 2023-05-31]
    sub   ed25519/CFABC5032E9CC2E8 2022-05-31 [S] [expires: 2023-05-31]

鍵をエクスポートする際、一般的には `--armor` （`-a`）を指定して base64 符号化してエクスポートすることが必要です。 Base64 符号化では、テキストとして鍵を印刷したりメールや掲示板へ投稿したりできます。ただし、秘密鍵を不意に公開・流出しないよう注意してください。

    $ gpg --export --armor alice
    -----BEGIN PGP PUBLIC KEY BLOCK-----

    glIXcCzcd9fsMoGs/wn8xhNmjGnzIMLDft93Vq0gtey8g9QPX154HNGH5OPOvCZU
    （中略）
    Wwp/nSZg
    =prkJ
    -----END PGP PUBLIC KEY BLOCK-----

### 削除

鍵が要らなくなったら、鍵輪から削除します。

- 公開鍵を削除： `--delete-keys`
- 秘密鍵を削除： `--delete-secret-keys`
- 公開鍵と秘密鍵を削除： `--delete-secret-and-public-keys`

### 失効

万が一自分の秘密鍵を失ったか秘密鍵が流出された場合、その鍵を失効させる必要があります。また、鍵が単に不要になった場合も、他人に失効証明書を配布した方がいいかもしれません。失効は厳密には鍵署名の一種で、失効対象をこれ以上信用すべきではないことを示します。

鍵全体の失効は以下のように行います。

- 秘密鍵を失った場合、保管されている失効証明書をインポートして、他人に配布する。
- まだ秘密鍵を持っている場合、失効証明書を生成してからインポートして、他人に配布する。

鍵生成時に失効証明書は同時に生成されるが、まだ秘密鍵を持っている場合、失効証明書を生成できます。 Base64 符号化が強制されます。他人が失効証明書を入手したら自分の鍵を勝手に失効させることができるため、失効証明書を独占的かつ安全に保管する必要があります。

    $ gpg --gen-revoke <key>

失効証明書を自分の鍵輪に適用するには、インポートします。

    $ gpg --import <revocation-cert>

また、副鍵や UID を失効させることが適切な場合があります。まだ秘密鍵を持っている場合、鍵編集で失効させることもできます。

- 鍵全体： `key 0` → `revkey`
- 副鍵： `key <N>` → `revkey`
- UID： `uid <N>` → `revuid`

## メッセージ

メッセージ（message）を対象に、 OpenPGP で暗号化したり署名したりできます。メッセージから OpenPGP データを生成する時に、メッセージがたいてい圧縮されます。

メッセージを元に、 GnuPG は以下の操作ができます。

- 暗号化と署名せずに OpenPGP 形式として保存（`--store`）
- 公開鍵暗号化（`--encrypt`）、パスワード暗号化（`--symmetric`）と標準署名（`--sign`）のあらゆる組み合わせ
- クリア署名（`--clear-sign`）（テキストメッセージの場合）
- 分離署名（`--detach-sign`）

暗号化、署名、圧縮などを管理可能にするために、 OpenPGP データを生成する送信クライアントはパケット（packet）を順序正しく生成する必要があります。 OpenPGP データを受信するクライアントは正しく逆操作（復号化、解凍、検証など）をします。

以下に OpenPGP における圧縮と暗号化について簡単に説明します。メッセージ署名は他のセクションで説明します。

### 圧縮

OpenPGP では一般的にメッセージ（と署名）が圧縮されます。この圧縮はメッセージのサイズを小さくし、暗号化のセキュリティを向上させる役割を果たします。

OpenPGP 標準で必ずしも義務化されていないだろうが、 OpenPGP データが生成される際の署名、圧縮と暗号化の順序関係はたいてい以下のとおりです。

- メッセージが署名される場合、メッセージは署名された後に署名とまとめて圧縮される。
- メッセージが暗号化される場合、メッセージ（と署名）は暗号化前に圧縮される。
- 署名と暗号化なしにメッセージが OpenPGP データとして保存される場合も、メッセージは圧縮される。

暗号化と署名をせずにメッセージを圧縮して OpenPGP 形式として保存するには、以下のコマンドを使用します。

    $ gpg [--output <out-message>] --store [--armor] [<in-message>]

### 暗号化

OpenPGP ではハイブリッド暗号化が使われます。送信クライアントは一度だけ使用するセッション鍵を生成し、セッション鍵をパスワード（サイファ）または公開鍵で暗号化します。

- 公開鍵暗号化： `--encrypt` （`-e`）
- パスワード暗号化： `--symmetric` （`-c`）

公開鍵暗号化の受信者は以下のように指定します。複数回使用可能です。

- 受信者を指定： `--recipient <key>` （`-r`）
- 匿名受信者を指定： `--hidden-recipient <key>` （`-R`）
- 全受信者を匿名にする： `--throw-keyids`

セッション鍵、公開鍵とパスワードの使用について、より具体的には以下のとおりです。

- 暗号化の際、セッション鍵でメッセージ（と署名）を暗号化する。暗号化の対象は一般的にメッセージ（と署名）を圧縮した結果。
- 公開鍵でなくパスワードだけで暗号化を行う場合、セッション鍵をパスワードから直接導出し、無作為のセッション鍵を使用しない。
- パスワードの有無によらず公開鍵で暗号化を行う場合、セッション鍵を無作為に生成し、どちらの公開鍵に該当する秘密鍵でも復号化できるように、各公開鍵でセッション鍵を暗号化する。パスワードから導出された鍵でセッション鍵を暗号化する。

メッセージを公開鍵暗号化とパスワード暗号化の両方で暗号化するには、以下のコマンドを使用します。（括弧と `...` 付きの `{`…`}...` は公開鍵の指定 `--recipient <key>` または `--hidden-recipient <key>` を一つ以上受け付けることを表し、文字通り入力しません）

    $ gpg [--output <out-message>] --encrypt --symmetric [--armor] \
    >   [--throw-keyids] {--recipient|--hidden-recipient <key>}... \
    >   [<in-message>]

その後、復号化してメッセージを出力させるには、以下の `--decrypt` （`-d`）コマンドを使用します。出力ファイルを指定しないで stdout を適切なファイル・パイプへ向けなければ、復号化されたメッセージが stdout のデフォルト（ターミナル）に流れることに注意してください。

    $ gpg [--output <recovered-message>] --decrypt <out-message>

### 埋め込みファイル名

メッセージから生成された OpenPGP データには埋め込みファイル名の欄が入っています。この欄はファイル名の長さ（バイト数）と文字列を受け入れます。

OpenPGP データを生成する時、メッセージのファイル名（stdin でない場合）の使用がデフォルトだが、以下のようにファイル名を空白に設定することを推奨します。また、 GnuPG には既にデフォルトかもしれないが、 OpenPGP データを処理する時に埋め込みファイル名を無視するよう、クライアントの環境設定に指定することも推奨します。

設定 | 関連クライアント | GnuPG コマンド
--- | --- | ---
埋め込みファイル名を指定 | 送信クライアント | `--set-filename ""`
埋め込みファイル名を無視 | 受信クライアント | `--no-use-embedded-filename`

埋め込みファイル名機能の無効化を推奨する理由は以下です。

- 埋め込みファイル名を空白にすれば、受信者が記憶装置にメッセージを書き込みたい場合に受信者に出力ファイル名を決めることを強制し、センシティブ情報の記憶装置への不意の書き込みを防ぐ。
- 埋め込みファイル名が空白でなければ、受信クライアント側のファイルが不意に上書きされる可能性がある。
- メッセージの内容に相応しい埋め込みファイル名を指定すると、メッセージの内容の手がかりになる。
- 埋め込みファイル名の欄はクライアントに対する攻撃手段であり、受信クライアントが無視すべき。（攻撃に使用された事例がある）

## 署名

OpenPGP において、署名はメッセージや公開鍵の完全性を認証の検証に広く使われています。暗号化と同様、署名もハイブリッド型で、署名対象データ自体に署名アルゴリズムが適用されず、署名対象データがハッシュ化されてから署名されます。

他の多くの暗号系と異なり、 OpenPGP ではメッセージや公開鍵だけでなく署名日時や署名発行鍵指紋などというメタデータも署名対象であることがほとんどです。そのため、 OpenPGP の署名は再現し難く、同じメッセージまたは公開鍵に何回か署名したら異なる署名を得ます。 OpenPGP データのパケットを表示する GnuPG コマンド `--list-packets` の出力に `hashed subpkt` を検索するとメッセージや公開鍵以外の署名対象データがより具体的にわかります。

GnuPG で署名する際、署名者鍵（鍵 ID や UID）を `--local-user <signer>` のように指定します。 `-u <signer>` のような短い指定方法も使用できます。

### メッセージ署名

メッセージ署名は、メッセージの完全性と認証を検証可能にするデータです。 OpenPGP には 3 種類のメッセージ署名があります。

- 標準署名： `--sign` （`-s`）
- クリア署名： `--clear-sign`
- 分離署名： `--detach-sign` （`-b`）

また、本セクションではメッセージ署名の検証について説明します。

#### 標準署名

標準署名（standard signature）はテキストまたはバイナリのメッセージによらず任意のメッセージに使える署名で、ファイルの平文の後に付け加える署名方法です。元のメッセージの復元に OpenPGP クライアントを必要とする形式で、メッセージと署名が出力されます。

暗号化と同時に使用でき、その場合、メッセージと署名がまとめて暗号化されます。メッセージを暗号化する場合によく使われる署名方法です。

メッセージに標準署名してからパスワード暗号化するには、以下のコマンドを使用します。（括弧と `...` 付きの `{`…`}...` は署名鍵の指定 `--local-user <key>` を一つ以上受け付けることを表し、文字通り入力しません）

    $ gpg [--output <out-message>] --sign --symmetric [--armor] \
    >   {--local-user <key>}... [<in-message>]

#### クリア署名

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA512

    Hello world!
    -----BEGIN PGP SIGNATURE-----

    iHUEARYKAB0WIQRFLPUBbLlzlH+zIZuv7OLMt8ZOKwUCYstVWgAKCRCv7OLMt8ZO
    K+87APwM+88+X7cLlQ27gm0Q8dvXviHIkkS/H9ybFfStdJn1gAD/SMeBEeoNZWS1
    TxwSN5iXFUECWnZ3vb0dSIOD5mSehA4=
    =wLhi
    -----END PGP SIGNATURE-----

クリア署名（cleartext signature）はテキストメッセージに使える署名で、テキストメッセージの平文の後に署名を base64 形式で付け加える署名方法です。以上の例に示すように、 OpenPGP クライアントを持っていなくてもメッセージ（`Hello world!`）を読めるが、 OpenPGP 形式としてメッセージと署名が出力されます。

メッセージの改行形式が変換されても（例えば Linux の LF から Windows の CRLF に）署名検証が成功します。テキストメッセージを暗号化せず、電子メールやメッセンジャーや掲示板などを配布経路として使う場合によく使われる署名方法です。

テキストメッセージにクリア署名するには、以下のコマンドを使用します。

    $ gpg [--output <out-message>] --clear-sign \
    >   {--local-user <key>}... [<in-message>]

#### 分離署名

分離署名（detached signature）はテキストまたはバイナリのメッセージによらず任意のメッセージに使える署名で、署名を別のファイルに出力させる署名方法です。受信者が OpenPGP クライアントを持っていなくても元のメッセージファイルを問題なく扱うことができるが、 OpenPGP クライアントを持っている受信者が署名検証できます。メッセージと署名が切り離されてなければならない場合（例えばソフトウェア）によく使われる署名方法です。

テキストメッセージに分離署名するには、以下のコマンドを使用します。

    $ gpg [--output <signature>] --detach-sign [--armor] \
    >   {--local-user <key>}... [<message>]

#### 署名検証

署名とメッセージの検証が成功した場合、以下の点が暗号上保証されます。

- メッセージの完全性
- メッセージの署名鍵
- 署名に付加された `hashed subpkt` のメタデータ（少なくとも署名日時と鍵指紋が付加されることが多い）

GnuPG で検証する際、エラーが発生しない限り `Good signature from "<UID>"` （正しい署名）または `BAD signature from "<UID>"` （正しくない署名）が表示され、署名者の鍵指紋や署名日時なども表示されます。また、署名が正しい場合に 0 の戻り値が返され、正しくない場合に 1 の戻り値が返され、エラーの時にそれ以外の値が返されます。

メッセージと署名がくっ付いていて平文な場合、検証するには、 `--verify` コマンドを使用します。

    $ gpg --verify <signed-message>

メッセージと分離署名の検証には、署名ファイルとメッセージファイルの両方を指定します。

    $ gpg --verify <signature> <message>

暗号文を復号化してメッセージと署名を検証するには、 `--decrypt` （`-d`）コマンドを使用して出力を捨てます。

    $ gpg --decrypt <out-message> > /dev/null

署名を検証する際、正しい署名という結果だけに頼らず、署名鍵、鍵信用と署名日時も確認することが重要です。残念ながら、署名鍵が信用されていなくても、署名が正しければ GnuPG は 0 （エラーなし）を返すため、 GnuPG 実行の戻り値に頼ることができません。署名検証の際、以下の点を確認した場合、メッセージを信用できる可能性が高いです。

- 署名日時が期待どおり。（未来や遠い過去ではない、または特定の日時に一致している）
- 署名鍵が期待どおり。（例えば、メッセージと全く関係ない鍵からの署名ではない）
- 署名鍵を信用している。（手動で確認した、または「完全」以上の鍵信用が計算された）
- 署名自体が正しい。（`Good signature ...` と表示された）

### 鍵署名

OpenPGP では公開鍵の完全性と認証を検証可能にするために公開鍵内のデータが署名されます。このような署名は一般的に鍵署名（key signature）と呼ばれます。また、 OpenPGP の公開鍵は事実上の証明書（certificate）であり、鍵署名は保証（certification）とも呼ばれます。例えば、公開鍵内の UID や副鍵を主鍵に結び付ける自己署名（self signature）があります。

他人の公開鍵への鍵署名という非自己署名もあります。鍵信用が不十分な場合に、クライアントは利用者に注意したりエラーを出したりすることがあります。鍵署名は他人の公開鍵の鍵信用を成立させる一つの方法です。

#### 他人の公開鍵に署名する前の検証

一般的には、非自己署名は、署名者が以下の 3 点の関係を十分に検証済みで、署名した公開鍵を保証することを示します。

- 鍵所有者
- 公開鍵
- UID の内容

検証方法といえば、署名者と鍵所有者の状況と希望次第です。鍵所有者を個人的に知っていること、メールアカウントの支配確認、身分証明書の確認、鍵所有者に手渡された公開鍵情報の鍵指紋の照合など、様々です。ただし、十分に検証されずに公開鍵が鍵署名されることが信用の輪にとって問題だと意識してください。

#### 鍵署名の発行

鍵所有者、公開鍵と UID との関係を十分に検証した後、検証した UID に鍵署名をします。 GnuPG では以下のコマンドで対象 UID `<target-UID>` と署名者鍵 `<signer>` （鍵 ID や UID）を指定して鍵署名をします。鍵署名には主鍵の秘密鍵が必要です。

    $ gpg --local-user <signer> --sign-key <target-UID>

ただし、ドクシング（doxxing）行為に当たるため、他人の公開鍵に署名しても、鍵サーバへの送信を含めて、インターネット上にアップロードしないでください。他人の公開鍵に署名した場合、直接その人に署名した公開鍵を安全に送ることを推奨します。

信用の輪を積極的に利用しない限り、他人の公開鍵をエクスポートしない方がいいでしょう。他人の公開鍵を信用することを記録したい場合にエクスポートできないローカル署名（local signature）で鍵署名することを推奨します。

    $ gpg --local-user <signer> --lsign-key <target-UID>

#### 鍵署名の検証

公開鍵の署名検証は `--check-sigs` コマンドで行います。

    $ gpg --check-sigs [<key>]

鍵署名の行は `sig` で始まり、他の記号で様々なフラグが示されます。失効した署名は `rev` で示されます。

記号 | 種類 | 位置 | 意味 | 備考
--- | --- | --- | --- | ---
`!` | 検証結果 | 1 | 署名が正しい |
`-` | 検証結果 | 1 | 署名が正しくない |
`%` | 検証結果 | 1 | 署名検証時にエラーが発生 | 例えばアルゴリズム非対応。
（なし） | 保証の検証度 | 2 | 署名者による鍵の検証度が不明 | 0x10 署名。
`1` | 保証の検証度 | 2 | 署名者が鍵を検証しなかった | 0x11 署名。
`2` | 保証の検証度 | 2 | 署名者が鍵を簡易検証した | 0x12 署名。
`3` | 保証の検証度 | 2 | 署名者が鍵を完全検証した | 0x13 署名。
`L` | 属性 | 3 | 署名はローカル（エクスポート制限） | `lsign` で発行。
`R` | 属性 | 4 | 署名は失効不可能 | `nrsign` で発行。
`P` | 属性 | 5 | 署名に方針（policy） URL がある |
`N` | 属性 | 6 | 署名に添付情報（notation）がある |
`X` | 状態 | 7 | 署名の期限が切れた | 通常は鍵署名に有効期限が切れない。
`[1-9T]` | 信用署名関連 | 8 | 信用署名のレベル | `tsign` で発行。

署名検証せずに鍵署名を表示するには `--list-sigs` を使用します。

## Base64 符号化

Base64 符号化は、 binary-to-text 符号化の一種で、 `A`–`Z`、 `a`–`z`、 `0`–`9`、 `+` と `/` の印刷可能文字（計 64 文字）に変換する符号化方式です。 Binary-to-text 符号化は、バイナリのデータを許容しない通信経路（紙への印刷、電子メール、インターネット掲示板、メッセンジャーなど）での通信に必要です。

各文字は 6 ビットの値を表し、各 3 バイト（24 ビット）のデータが 4 文字で表されます。元のデータのバイト数が 3 で割れない場合に数ビットが余るため、パディング（padding）バイト数を表す `=` の文字が追加されます。 Base64 符号化されたデータは元のデータより約 4/3 の割合で大きくなります。

元のデータ | 16 進数 | base64 符号化
--- | --- | ---
`Hello world!` | 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 | `SGVsbG8gd29ybGQh`
`Hello world` | 48 65 6c 6c 6f 20 77 6f 72 6c 64 | `SGVsbG8gd29ybGQ=`
`Hello worl` | 48 65 6c 6c 6f 20 77 6f 72 6c | `SGVsbG8gd29ybA==`

OpenPGP ではこの符号化を “ASCII armor” と呼ばれます。 OpenPGP の base64 符号化データは以下の構造です。ただし、メタデータには完全性と認証がなく、誰でもが簡単に捏造・改竄・削除できるため、信用すべきではありません。

- ヘッダ（データの種類に該当する 1 行）：
  - `-----BEGIN PGP MESSAGE-----`：メッセージ
  - `-----BEGIN PGP PUBLIC KEY BLOCK-----`：公開鍵
  - `-----BEGIN PGP PRIVATE KEY BLOCK-----`：秘密鍵
  - `-----BEGIN PGP SIGNATURE-----`：署名
  - …
- メタデータ（0 行以上）：
  - `Version`：符号化を行った OpenPGP クライアントバージョン情報
  - `Comment`：任意に追加できるコメント（UTF-8 文字列）
  - …
- 空白の行（1 行）
- base64 符号化データ
- `=` ＋ base64 符号化データの 4 文字チェックサム（1 行）
- フッタ（ヘッダに該当する 1 行）

以下は base64 符号化のメッセージの例です。 GnuPG で OpenPGP データを生成するコマンドに `--armor` （`-a`）を追加することでデータを base64 符号化して出力させます。

    -----BEGIN PGP MESSAGE-----

    jA0ECQMKFE/lM/98gpr/0kgB4aENgiZM5m7E1rzJjvFlVCysmotbughjfTUKHdM1
    5CrsxkYmsImIo8bUN6rzHUSkpIpNEfOYyghKsUXe7U3nTJqiFme58Ko=
    =ewzX
    -----END PGP MESSAGE-----

クリア署名の構造は似ているが若干違います。具体的には、以上に説明した構造の前に、以下が `-----BEGIN PGP SIGNATURE-----` の直前に付加されます。

- `-----BEGIN PGP SIGNED MESSAGE-----`：署名されたメッセージ（1 行）
- `Hash`：署名に使用されたハッシュ関数（1 行）
- 空白の行（1 行）
- メッセージの内容

## 鍵サーバ

鍵サーバ（keyserver）は OpenPGP 利用者が自分の公開鍵の配布に使用でき、鍵交換を促進するサーバです。公開鍵をエクスポートして、鍵サーバにアップロードしたら、他人がいつでも自由にその公開鍵を入手できます。

OpenPGP の普及を進めながら検閲耐性を目的とした SKS （synchronizing key server）同期化鍵サーバネットワークが立ち上がりました。 SKS には以下の特徴があります。

- 分散型とノード間同期化：ネットワーク故障問題や検閲への耐性
- 付加専用：上書き・削除の不可能性による検閲耐性
- 非認証：
  - 誰でもが身元を明かさずに検索・配布・入手ができる
  - ある程度の匿名性（ただし、ネットワーク監視での特定が可能）

しかし、特に SKS には様々な問題があります。例えば、全く非認証なため、誰でもが他人の公開鍵をアップロードでき、付加専用なため取り返しが付きません。そのため、以下の推奨を検討してみてください。

- ドクシングに当たるため、他人の公開鍵をアップロードしない。
- 他人の公開鍵に鍵署名した場合、その人に直接かつ安全に送る。
  - 例えば、相手の公開鍵宛に鍵署名した公開鍵を暗号化して送る。
- 自分の公開鍵を配布したい場合：
  - SKS へのアップロードを避ける。
  - ある程度の認証と編集・削除可能性のある鍵サーバを利用する。
  - 自分が支配するアカウントやウェブサイト上に公開鍵を載せる。
- 匿名化ネットワーク（例えば Tor）経由と転送時暗号化（例えば TLS）で鍵サーバにアクセスする。
- GnuPG で定期的に公開鍵を更新したい場合、プライバシー保護を目的とした Parcimonie を使用してみる。
- 公開鍵の入手・インポートの頻度が低い場合、 GnuPG の鍵サーバアクセスを（`--disable-dirmngr` で）無効化し、入手した公開鍵を（`--show-keys` で）確認した上でインポートする。

→ 外部資料： Parcimonie： `https://salsa.debian.org/intrigeri/parcimonie`

## 信用

何かしらの方法で公開鍵を手動で確認したり相手を個人に知っていたりしている場合に自信をもってその人の公開鍵が使えるが、個人的に知らない人や会ったことさえない人の公開鍵をどうやって信用できるでしょうか？

OpenPGP では利用者が他の利用者の公開鍵に署名することで、信用（trust）を示したり与えたりします。他人の公開鍵を何かしらの方法で確認できた後に自分の主鍵でその公開鍵に鍵署名することで、「この公開鍵を信用します」という情報をその公開鍵に付加できます。一方、公開鍵をインポートする際、公開鍵に付加された鍵署名を検証することで信用度を評価できます。

この習慣が実践されている代表例といえば、 Debian コミュニティです。 Debian 貢献者の公開鍵はその人の身元証明書らしきものとして扱われ、年例の DebConf （Debian カンファレンス）で鍵署名パーティ（key signing party）が開催されることが多いです。

→ 外部資料：鍵署名パーティ： `https://debconf22.debconf.org/talks/51-continuous-key-signing-party-introduction/`

### 所有者信用と鍵信用

このように OpenPGP 利用者が互いの公開鍵に署名することで、公開鍵の連鎖が出来上がります。その連鎖を基に、信用の輪という信用モデルを用いて他人の公開鍵の信用度を評価できます。 OpenPGP では、信用の輪に関する以下の信用概念があります。

- 所有者信用（owner trust または “trust”）：「この公開鍵の所有者は他の公開鍵をしっかり検証してから鍵署名をする人だ」と信じる時に OpenPGP 利用者自身が各公開鍵（所有者の検証能力）に与える信用。
- 鍵信用（key trust または “validity”）：「この公開鍵は間違いなくその人が支配するものだ」「信用している人がこの公開鍵を信用している」などと信じる時、鍵署名から公開鍵を信用できると確認できた時などに公開鍵に与える信用。

### 信用モデル

信用の輪（web of trust）、直接信用（direct trust）などという信用モデル（trust model）があります。オプション `--trust-model` で信用モデルを指定します。

- 直接信用（`direct`）：ある利用者自身が各公開鍵の信用を自由自在に決める。（鍵信用は利用者自身が与えた所有者信用だけで決まる）
- 信用の輪（`pgp`）：互いの公開鍵に積極的に鍵署名されることで出来上がった連鎖を活用して、ある利用者自身が与えた所有者信用と鍵署名から各公開鍵の信用を計算。
- 全て信用（`always`）：ある利用者が（失効・期限切れ・無効化した鍵を除いて）全公開鍵を信用。（外部の公開鍵確認方式を使用しているか実験をしている場合だけに使用）

公開鍵が OpenPGP クライアントに最終的に信用されるかは、信用モデルから導出された鍵信用次第です。

### 信用度

鍵信用が完全信用（full trust）以上ではない場合、クライアントは利用者に注意したりエラーを返したりなどをします。不完全信用（marginal trust）という信用度は、所有者信用の不完全な公開鍵が他人の公開鍵に署名した時に与えられます。信用しない（never trust）という信用度も与えることも可能です。その他に、失効した、期限が切れた、信用不明などの信用度もあります。

信用度 | 識別子*1 | 識別子*2 | 識別子*3 | 識別子*4 | 意味・備考
--- | --- | --- | --- | --- | ---
究極 | 5 | 6 | `u` | `ultimate` | 利用者自身だけに該当。
完全 | 4 | 5 | `f` | `full` | 所有者または鍵を完全に信用。
不完全 | 3 | 4 | `m` | `marginal` | 所有者または鍵に対する信用度が低い。
未定義 | 1 | 2 | `q` | `undef` | 信用度を未定義として指定された。
不明 | （なし） | （なし） | `-` | `unknown` | 信用度が不明。公開鍵インポート時のデフォルト。
信用しない | 2 | 3 | `n` | `never` | 所有者または鍵を信用しない。
期限切れ | （なし） | 1 | `e` | `expired` | 鍵の期限が切れたか期限が切れた鍵で信用度を計算。
失効 | （なし） | （なし） | `r` | `revoked` | 鍵が失効した。鍵信用だけに該当。
エラー | （なし） | （なし） | `?` | `error` | 不正な信用値などがあった場合に発生。

- *1：鍵編集の `trust` サブコマンドに使用。
- *2：所有者信用のエクスポートとインポートの時に使用。
- *3：オプション `--with-colons` で鍵を表示する時に表示される。
- *4：鍵を表示する時に表示される。

### 鍵署名と信用の管理・活用

OpenPGP クライアントが導出した信用の輪の結果だけに頼らずに、他の確認手段も取った方がいいでしょう。もしかしたら鍵が失効したか単に所有者に放棄されたかもしれません。鍵署名と信用の輪に様々な問題があることを意識してください。とはいえ、他の手段である程度確認した公開鍵を、信用の輪を活用して信用を更に確認できます。

ソーシャルグラフを漏らさない鍵署名と信用の管理について、以下の推奨を検討してみてください。

- 共通の推奨：
  - 鍵署名を一般的にローカル署名 `--lsign-key` で行う。
  - エクスポートしたい鍵署名だけを普通の鍵署名 `--sign-key` で行う。
  - `--export-options export-minimal` 設定を環境設定ファイルに追加して、不意の鍵署名エクスポートを防ぐ。
- 環境設定ファイルに信用モデルを直接信用（`direct`）に設定：
  - 鍵信用を簡単かつ完全にコントロール可能。
  - 鍵信用を `--edit-key` のサブコマンド `trust` で指定。
  - 主鍵での鍵署名を行わないため、主鍵をオフライン保存できる。
  - 信用の輪を活用したくても、信用モデルの切り替えが不便。
- 環境設定ファイルに信用モデルを信用の輪（`pgp`）に設定：
  - 信用の輪をいつでも簡単に活用できる。
  - 他人の公開鍵の検証能力に応じて、所有者信用を設定。
  - 公開鍵を信用している場合、鍵署名をして鍵信用を完全信用にする。
  - 主鍵での鍵署名を必要とするため、主鍵をオフライン保存できない。

## 鍵ストレッチング

OpenPGP では、パスワードを用いた暗号化を使用時に、パスワードを総当たり攻撃や辞書攻撃から保護する s2k 鍵ストレッチングアルゴリズムを用いて、パスワードから鍵が導出されます。具体的には以下の場合に s2k が用いられます。

- 秘密鍵の鍵データの暗号化：パスワードから導出した鍵で鍵データを暗号化。
- メッセージの対称鍵暗号化：
  - パスワードだけで暗号化を行う場合、セッション鍵をパスワードから直接導出してメッセージを暗号化。
  - パスワードと公開鍵の両方で暗号化を行う場合、パスワードから導出した鍵で無作為のセッション鍵を暗号化。

メッセージの対称鍵暗号化の際、 GnuPG のオプションで以下の s2k パラメータを変更できます。

オプション | オプション | 推奨値 | 備考
--- | --- | --- | ---
モード | `--s2k-mode` | 3 | ソルト化＋繰り返し計算。デフォルト。
繰り返し回数 | `--s2k-count` | 65011712 | 最大値。
使用ハッシュ関数 | `--s2k-digest-algo` | SHA512 | 導出鍵の計算に使用。
使用サイファ | `--s2k-cipher-algo` | AES256 | 導出鍵での暗号化に使用*1。

- *1：パスワードだけで暗号化を行う場合、 `--s2k-cipher-algo` より `--personal-cipher-preferences` または `--cipher-algo` の方が優先される。

ただし、秘密鍵の保護には以上のオプションが適用されず、デフォルトとして 100 ミリ秒の計算時間に調整された SHA1 を用いたソルト化＋繰り返し計算で保護されます。繰り返し回数は `gpg` でなく `gpg-agent` の `--s2k-count` オプションで調整できるが、残念ながら使用ハッシュ関数は SHA1 に固定されています。

→ 外部資料： s2k オプションの秘密鍵への不適用に関する背景： `https://dev.gnupg.org/T1800`

# 注意点と限界

OpenPGP は使用が難しく、様々な落とし穴と限界があります。普及低迷、法的問題、組織的運用の問題などもあります。

→ 外部資料： GNU Privacy Guard 講座 § 暗号運用の問題点： `https://gnupg.hclippr.com/papers/problem/index.html`

→ 外部資料： GNU Privacy Guard 講座 § 会社環境での暗号運用の問題点： `https://gnupg.hclippr.com/papers/company/index.html`

## 秘密鍵の守秘は重大

OpenPGP のセキュリティは秘密鍵が守られることが大前提となっています。秘密鍵が他人に漏れるように危殆化したら、その他人が元の鍵所有者の公開鍵で暗号化したメッセージを復号化したり元の秘密鍵所有者をなりすましたりできるようになってしまいます。また、 OpenPGP は前方秘匿（forward secret）な暗号系ではないため、秘密鍵が危殆化したら全ての暗号文の秘匿性に影響を及ぼし、暗号文を収集する攻撃者に対して危殆化の影響が大きいです。

そのため、秘密鍵は鍵所有者が独占的かつ安全に保管し、秘密鍵を厳重に守るべきです。 OpenPGP の秘密鍵はパスワードで保護されるが、その保護だけに頼っては危険でしょう。また、 OpenPGP の前方秘匿の欠如への対策として、定期的に新しい鍵を生成・採用した方がいいかもしれません。

→ ガイド：暗号技術入門 § 自分の秘密鍵を自分で保管する — Markdown | HTML

しかし、一部の OpenPGP クライアントは以上の秘密鍵保管原則を破ります。典型的な例といえば、秘密鍵をサービス提供者のサーバにアップロードさせる OpenPGP 対応ウェブメールクライアントです。この場合、サービス提供者は悪質なウェブクライアントを利用者に送ってパスワードを盗み取るなどして利用者の秘密鍵を不正に入手できるため、安全ではないと言えるでしょう。

秘密鍵が危殆化した後に鍵所有者が該当する公開鍵を失効させていない間に、危殆化した鍵所有者の公開鍵を他人が不意に使い続けてしまいます。万が一秘密鍵が危殆化した場合、その鍵をもう信用すべきではないことを示すよう鍵を失効させるべきです。

## メタデータをほぼ全く保護しない

OpenPGP のデータ（メッセージ、鍵、署名など）には鍵 ID、使用アルゴリズム、パケットサイズ、日時などという OpenPGP 動作に重要なメタデータが添付されるため、 OpenPGP データを入手した人にこのようなメタデータが漏れます。また、 OpenPGP の公開鍵には鍵指紋、各鍵の機能、 UID、生成日時、有効期限、自己署名、他の鍵からの鍵署名、公開鍵アルゴリズム、優先特徴リストなどの公開鍵情報が見えます。例えば、標的の公開鍵に入っている鍵署名を見るだけで、攻撃者は標的のソーシャルグラフ（人間関係）を知ることができます。

OpenPGP はトランスポートプロトコルでなく、データ転送にトランスポートプロトコルを使用する必要があります。 OpenPGP の下のトランスポートプロトコルを使うと当然ながらそのプロトコルのメタデータが漏れます。例えば、電子メールの場合、 OpenPGP は本文の内容を秘匿化するが、宛先、送信元、件名、 IP アドレス、日時などを保護しません。

以上のメタデータから、利用者の OS やクライアントの特定、利用者に対する指紋抽出などという様々な利用者識別攻撃が可能です。特に複数の鍵ペアを使用する利用者がこのリスクを意識した方がいいです。

## オプション、対応アルゴリズム、悪特徴、安全でないデフォルト

OpenPGP はよかれ悪しかれ後方互換性にこだわるため、オプションや対応アルゴリズムが過多で、安全でないデフォルトを採用しているクライアントが珍しくありません。

多くのクライアントにはクライアント情報やコメントの出力などという悪特徴も存在します。例えば、 GPGTools で公開鍵をエクスポートすると、デフォルトでは以下のようなクライアント関連コメントが出力され、これはメタデータ漏れの一例です。

    -----BEGIN PGP PUBLIC KEY BLOCK-----
    Comment: GPGTools - http://gpgtools.org

    （中略）
    -----END PGP PUBLIC KEY BLOCK-----

一部のクライアントはオプションやアルゴリズムに制限をかけるが、例えば GnuPG は柔軟過ぎます。そのため、ある OpenPGP クライアントを使用する前に、脆弱なアルゴリズム、オプション、悪特徴などを避けたり無効化したりすることを推奨します。

## 脆弱な OpenPGP 対応メールクライアント

OpenPGP 対応メールクライアントが多くあるが、脆弱性が発見されたクライアントが珍しくなく、他にも脆弱性があるでしょう。

→ 外部資料： “Johnny, you are fired!”： `https://www.usenix.org/conference/usenixsecurity19/presentation/muller`

仮に自分だけが安全に OpenPGP を使用しているとしても、他人のメールクライアントや使用習慣が安全でなければ、 OpenPGP メールの安全は他人の水準に落ちてしまいます。そのため、 OpenPGP メールは一般的には安全ではないと思います。

OpenPGP 対応ウェブメールクライアントについて前述したが、秘密鍵に対するリスクがデバイス上のメールクライアントより高いと言えます。

## 使い難さとミスしやすさ

批判は主に OpenPGP メールについてかもしれないが、廃止すべきだと訴える人がいるほど、 OpenPGP は使い難くて使用ミスをしやすいという問題があります。これは OpenPGP の最大な欠点だと言っても過言ではありません。

問題の原因はおそらく一般人の暗号概念とデジタルの理解不足、セキュリティ意識の低さ、クライアントの使い難さとオプションの過多の何かしらの組み合わせでしょう。

発案されてから数十年が経ったものの、主にこの問題によって OpenPGP の普及は特定のグループ、セキュリティ要件の高い人、セキュリティ専門家、ソフトウェア開発者などにとどまり、一般人に及んでいません。

メールクライアントの実装問題に加えて、この使用困難さとミスしやすさの問題によって OpenPGP メールの不便さと危険性が更に高まります。署名の確認ミスによるなりすましや改竄のリスク、暗号化の使用ミスまたは有効化忘れによる平文の流出、鍵の期限が切れたか失効したかの場合への対応の混乱、鍵管理の問題など、様々な落し穴があります。

→ ガイド：暗号技術入門 § 不便性や使用ミスによるセキュリティリスク — Markdown | HTML

## 鍵署名と信用の輪に関する問題

OpenPGP では「この公開鍵を信用します」という他人の公開鍵への署名をすることができ、鍵署名の連結に基づく信用の輪から信用の計算が可能です。

しかし、信用の輪と鍵署名には問題があり、一般的には推奨しません。

- 他人の公開鍵に署名するまで信用の輪を維持する価値があるか疑わしい。
- 信用の輪は莫大なソーシャルグラフ情報で、かなりのプライバシー問題。
- 鍵署名する前に相手の政府発行の身分証明書の提示を要求する人が多く、匿名・仮名での活動を妨害したり身分証明書関連リスク（紛失、盗難、個人情報漏洩など）を高めたりする。
- 署名する前に相手の公開鍵をしっかり確認しない人が少なくなく、これが信用の輪の完全性減少につながりかねない。
- 誰でもが勝手に他人の鍵に署名でき、これが鍵所有者の同意に反したり悪質情報の普及につながったりする。

## 鍵サーバを使わない方がいいかも？

OpenPGP 公開鍵のデータベースを管理している鍵サーバがあります。他人の公開鍵の入手や自分の公開鍵の配布には役立つが、 SKS （synchronizing key server）には注意すべき問題があります。

付加専用（編集と削除が不可能）である従来の鍵サーバに公開鍵を一回でもアップロードしたら、その情報が永久に SKS 上に保存されてしまいます。鍵を編集したり失効させたりしても情報が鍵サーバに残り、情報を削除しようがありません。

また、 SKS へのアップロードは全く非認証でもあるため、誰でもが虚偽の公開鍵や悪質情報をアップロードしたり他人の公開鍵を勝手にアップロードしたりできます。例え自分の公開鍵を他人に鍵サーバにアップロードされたくなくても誰かにアップロードされるかもしれないことを意識すべきです。防止策といえば、残念かつ皮肉ながら自分の公開鍵を公開しないでやりとりしたい人だけに公開鍵を渡すぐらいしかありません。

付加専用と非認証の特性を逆手に、 SKS は悪用、プライバシー問題と GDPR 遵守（例：忘れられる権利）に関して苦戦しています。 2019 年 6 月、 SKS が公開鍵スパム（送り付け）攻撃を受け、被害を受けた公開鍵をインポートした OpenPGP クライアントが破壊されるという事例がありました。 GnuPG 2.2.17 にこの攻撃に対する防御が追加されたが、被害を受けた公開鍵はまだ SKS に残っているでしょう。

→ 外部資料： CVE-2019-13050： `https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-13050`

→ 外部資料： 2019 年の SKS スパム攻撃： `https://gist.github.com/rjhansen/67ab921ffb4084c865b3618d6955275f`

自分の公開鍵を公開したい場合、自分が管理・支配するウェブサイト上などに公開鍵を公開することを推奨します。その代わりに、鍵サーバを特に利用したい場合、アップロード認証を必要とし、公開鍵の編集と削除が可能な鍵サーバの使用を推奨します。例えば、 2019 年 6 月の公開鍵スパム攻撃の後に立ち上げられた `keys.openpgp.org` があります。

## 署名の検証と解釈に関する問題

署名が完全性と認証を検証可能にするデータは署名されたデータだけです。 OpenPGP メッセージ署名の場合、署名対象データは一般的にメッセージ、署名日時と署名鍵指紋です。 OpenPGP データは様々な通信経路上で配布されたり様々なファイルシステム上で保存されたりするが、当然ながら、このような下部のプロトコルに関する完全性や認証を、 OpenPGP の署名は全く提供しません。また、 OpenPGP は暗号化者（データを暗号化した人）の認証を提供しません。

例えば、 OpenPGP メールでは Alice の鍵に署名され、 Bob 宛に暗号化されたメッセージについて、以下を暗号上確認できません。

- Alice がメッセージを執筆したこと。（ただし Alice がメッセージに署名したことが検証できる）
- Alice がメッセージを暗号化したこと。
- Alice が暗号文を送信したこと。
- 暗号文が Bob に送信されたこと。
- 送信と受信の日時。

Bob がこの暗号文を受信して、メッセージと署名を復元したとしても、 Bob が全く同じメッセージと署名を Carol 宛にしたらどうなるでしょうか？その場合、 Alice がメッセージに署名したことを検証可能だが、今回は暗号化者と送信者は Alice ではなく Bob です。また、このように署名されたメッセージを文脈から外されると、変に解釈される可能性があります。

## 鍵指紋に関する問題

注：現在検討されている OpenPGP 草案は SHA-256 を用いた新しい鍵指紋計算手法を提案しています。

鍵指紋の計算には脆弱な SHA-1 ハッシュ関数が使用されます。もし攻撃者がある鍵指紋に該当する公開鍵を自由自在に生成できるようになった場合、鍵指紋を用いた公開鍵の指定・特定の安全が失われます。

さらに注意すべきことは、 64 ビットの鍵 ID についてです。鍵 ID の照合だけで入手した公開鍵を検証したら、攻撃者の公開鍵または間違った公開鍵を誤って信用するリスクがあります。

## メールアドレスの公開とメールの使用への圧力

OpenPGP 仕様は `氏名 (コメント) <メールアドレス>` という UID 形式を推奨し、一部のクライアントはこの形式を強制します。

例えば、 `--allow-freeform-uid` を指定しない限り、 GnuPG は鍵生成時に実名やメールアドレスを聞き、デフォルトとしてこの UID 形式を強制します。鍵サーバ `keys.openpgp.org` はメールアドレスが記載されている UID しか受け入れません。一部のメールクライアントは、連絡先のメールアドレスが UID に記載されたメールアドレスに一致しなければ公開鍵を拒否します。

OpenPGP メールに様々な問題があり、メールアドレス（個人情報）の公開と電子メールの使用を励ましているため、この UID 形式の強制は残念です。

## 長期鍵の問題

OpenPGP は利用者が鍵を長期的に使用・管理できるよう、後方互換性を重視しています。

長期鍵は鍵署名という「信用」の収集には便利だが、本当に長期的に信用に値するのでしょうか？ 10 年以上前に生成された鍵や DSA 公開鍵アルゴリズムの鍵は現在もまだ使われています。長期鍵にはいくつかのリスクがあります。

- OpenPGP に前方秘匿性がないため、生成時からの経過時間つれて、鍵が危殆化した場合に危惧される暗号文の数が多くなる。
- 生成時からの経過時間つれて、鍵が危殆化したか放棄された可能性が増す。
- 古い鍵は脆弱な公開鍵アルゴリズムを使用している傾向がある。
- 同じ鍵の繰り返しの使用期間が長くなるにつれて、活動の追跡・繋がりの手がかりとなる情報がより多く漏れる。（より多くの鍵輪にインポートされ、より多くの他人の鍵に署名され、より多くの他人の鍵に署名し、より多くの暗号文や署名に鍵 ID または鍵指紋として記載される）

そのため、鍵の有効期限より、鍵の生成日時や公開鍵アルゴリズムの情報の方が、鍵が信用に値するかという判断に役立つでしょう。また、定期的に新しい鍵を生成して移行すると、まだ脆弱とされていない公開アルゴリズムに移行したり鍵の危殆化に伴う影響を最小限にしたりすることができます。

## 公開鍵の大きさ

大きな問題ではなく単なる不便だけだが、 OpenPGP の公開鍵は（バイト数ではかると）大きいです。主鍵と 1 つの副鍵だけある比較的単純で小さな楕円曲線公開鍵さえ半キロバイト程度です。鍵署名を多く収集した長期鍵、副鍵の回転の多い鍵、 2048 ビット以上の RSA 鍵などは何倍も大きいです。

そのため、 QR コード化したり名刺で渡したりはなかなかできず、公開鍵の鍵指紋（と公開鍵の入手方法）が必要です。

# GnuPG コマンド一覧

本セクションでは主要 GnuPG コマンドを紹介します。

以下のコマンドは Bash シェルを前提にしています。 Windows のコマンドプロンプトや PowerShell などではコマンドが失敗するか問題が発生する可能性があります。

各コマンドが受け入れるオプションをほとんど省略しています。また、ファイルの指定が求められる場合、 stdin や stdout の指定を省略できることが多く、省略できない場合に `-` で指定します。詳しくは GnuPG の manpage を参照してください。

## 鍵操作

- 鍵ペアを生成する

    $ gpg --full-gen-key --expert

- 鍵を編集する

    $ gpg --edit-key [--expert] <key>

- 鍵を編集する際、サブコマンドのリストと説明を表示する

    $ gpg --edit-key [--expert] <key>
    gpg> help

- 副鍵を追加する

    $ gpg --edit-key <key>
    gpg> addkey

- UID を追加する

    $ gpg --edit-key <key>
    gpg> adduid

- 鍵機能を変更する

    $ gpg --edit-key <key>
    gpg> key <N>
    gpg> change-usage

- 秘密鍵のパスワードを変更する

    $ gpg --edit-key <key>
    gpg> passwd

- 優先特徴リストを表示する
  - 備考：表示サブコマンド `pref` は更新サブコマンド `setpref` に対応する

    $ gpg --edit-key <key>
    gpg> pref
    gpg> showpref

- 優先特徴リストを変更する
  - 備考：優先特徴リストの表示サブコマンド `pref` の形式の文字列を受け入れる

    $ gpg --edit-key <key>
    gpg> setpref <preferences>

- 優先鍵サーバを変更する

    $ gpg --edit-key <key>
    gpg> keyserver

- 署名機能のある副鍵に主鍵と副鍵を結びつける副鍵からの鍵署名を追加する

    $ gpg --edit-key <key>
    gpg> key <N>
    gpg> cross-certify

- 公開鍵を表示する（`-k`）

    $ gpg --list-keys [<key>]

- 秘密鍵を表示する（`-K`）

    $ gpg --list-secret-keys [<key>]

- 公開鍵を表示する際、鍵指紋も表示する
  - 備考： 2 回指定すると副鍵の鍵指紋も表示する

    --with-fingerprint

- 公開鍵を表示する際、鍵グリップも表示する

    --with-keygrip

- ファイルから鍵を表示する

    $ gpg --show-keys [<key-file>]

- ファイルから鍵をインポートする

    $ gpg --import [<key-file>]

- 鍵をインポートする際、最小化した鍵をインポートする

    --import-options import-minimal

- 鍵をインポートする際、復元用データもインポートする
  - 備考：エクスポート時の `--export-options backup` に対応

    --import-options restore

- ファイルへ公開鍵をエクスポートする

    $ gpg [--output <key-file>] [--armor] --export <key>

- ファイルへ公開鍵と秘密鍵をエクスポートする

    $ gpg [--output <key-file>] [--armor] --export-secret-keys <key>

- ファイルへ公開鍵と秘密鍵（副鍵だけ）をエクスポートする

    $ gpg [--output <key-file>] [--armor] --export-secret-subkeys <key>

- 鍵をエクスポートする際、最小化した鍵をエクスポートする

    --export-options export-minimal

- 鍵をエクスポートする際、復元用データもエクスポートする
  - 備考：エクスポート時の `--import-options restore` に対応

    --export-options backup

- 公開鍵を削除する

    $ gpg --delete-key <key>

- 秘密鍵を削除する

    $ gpg --delete-secret-keys <key>

- 公開鍵と秘密鍵を削除する

    $ gpg --delete-secret-and-public-keys <key>

- 副鍵を指定して削除する

    $ gpg --edit-key <key>
    gpg> key <N>
    gpg> delkey

- UID を指定して削除する

    $ gpg --edit-key <key>
    gpg> uid <N>
    gpg> deluid

- 失効証明書を生成する

    $ gpg --gen-revoke <key>

- 鍵全体を失効させる

    $ gpg --edit-key <key>
    gpg> key 0
    gpg> revkey

- 副鍵を指定して失効させる

    $ gpg --edit-key <key>
    gpg> key <N>
    gpg> revkey

- UID を指定して失効させる

    $ gpg --edit-key <key>
    gpg> uid <N>
    gpg> revuid

- 鍵署名をする

    $ gpg [--local-user <signer>] --sign-key <target-UID>

- エクスポート不可能な鍵署名をする

    $ gpg [--local-user <signer>] --lsign-key <target-UID>

- 最新の自己署名以外の全ての鍵署名を削除して鍵を最小化する

    $ gpg --edit-key <key>
    gpg> minimize

- 鍵署名を検証する

    $ gpg --check-sigs [<key>]

- 署名検証せずに鍵署名を表示する

    $ gpg --list-sigs [<key>]

- 鍵輪を使用しない

    --no-keyring

- デフォルトの鍵輪を使用リストから除外する

    --no-default-keyring

- 鍵輪を使用リストに追加する
  - 備考：複数回指定できる

    --keyring <keyring>

## メッセージ操作

- 暗号化や署名をせずに OpenPGP 形式として保存する

    $ gpg [--output <out-message>] --store [--armor] [<in-message>]

- 公開鍵で暗号化を行う（`-e`）

    $ gpg [--output <out-message>] --encrypt [--armor] [<in-message>]

- 公開鍵暗号化を行う際、受信者の公開鍵を指定する（`-r`）
  - 備考：複数回指定できる

    --recipient <recipient>

- 公開鍵暗号化を行う際、受信者の公開鍵を匿名にして指定する（`-R`）
  - 備考：複数回指定できる

    --hidden-recipient <recipient>

- 公開鍵暗号化を行う際、全受信者を匿名化する

    --throw-keyids

- パスワードで暗号化を行う（`-c`）

    $ gpg [--output <out-message>] --symmetric [--armor] [<in-message>]

- 標準署名をする（`-s`）

    $ gpg [--output <out-message>] --sign [--armor] [<in-message>]

- クリア署名をする

    $ gpg [--output <out-message>] --clear-sign [<in-message>]

- 分離署名をする（`-b`）

    $ gpg [--output <signature>] --detach-sign [--armor] [<message>]

- 署名を行う際、署名者を指定する（`-u`）
  - 備考：複数回指定できる

    --local-user <signer>

- 署名を行う際、メッセージをテキストとして解釈すべきという署名をする

    --textmode

- 標準署名またはクリア署名された平文メッセージを検証する

    $ gpg --verify [<signed-message>]

- 分離標準された平文メッセージを検証する

    $ gpg --verify <signature> <message>

- 暗号文を復号化してメッセージを出力する（`-d`）

    $ gpg [--output <out-message>] --decrypt [<in-message>]

- 暗号文を復号化して署名されたメッセージを検証する

    $ gpg --decrypt [<message>] > /dev/null

- 匿名受信者のある暗号文を復号化する際、復号化鍵を指定して復号化を試みる
  - 備考： `--hidden-recipient` または `--throw-keyids` が使われた場合に役立つ

    --try-secret-key <key>

- 暗号文を復号化する際、暗号文内の鍵 ID を無視して全ての復号化鍵で復号化を試みる
  - 備考：虚偽の受信鍵 ID が埋め込まれた場合に役立つ

    --try-all-secrets

- 暗号文を復号化してセッション鍵を表示する
  - 備考：平文を明かすよう脅迫されていたり通信経路経由で迷惑・悪用に当たる暗号文を報告したりの場合、（秘密鍵またはパスワードを渡さずに）一通の暗号文のセッション鍵だけを渡すことを可能にする
  - 備考：セッション鍵を stderr に出力する
  - 備考：セッション鍵を使用するオプション `--override-session-key` に対応する
  - 備考：セッション鍵の `:` の前の数字はサイファを識別する数字

    $ gpg --decrypt --show-session-key [<message>] > /dev/null

- セッション鍵を指定して暗号文を復号化する
  - 備考：セッション鍵を表示するオプション `--show-session-key` に対応する

    $ gpg --no-keyring --override-session-key <session-key> \
    >   [--output <out-message>] --decrypt [<in-message>]

## 信用操作

- 所有者信用データをインポートして既存のデータを更新する
  - 備考：エクスポート `--export-ownertrust` 形式のデータを受け入れる

    $ gpg --import-ownertrust < <trust-file>

- 以前のデータを削除して所有者信用データをインポートする
  - 備考：エクスポート `--export-ownertrust` 形式のデータを受け入れる

    $ rm ~/.gunpg/trustdb.gpg
    $ gpg --import-ownertrust < <trust-file>

- 所有者信用データをエクスポートする
  - 備考：インポート `--import-ownertrust` に受け入れられる

    $ gpg --export-ownertrust > <trust-file>

- 鍵の所有者信用を変更する
  - 備考：全ての UID に適用される

    $ gpg --edit-key <key>
    gpg> trust

- ある操作をする際、指定した鍵を信用する

    --trusted-key <key>

## 他の操作

- GnuPG ヘルプを表示する（`-h`）

    $ gpg --help

- バージョン情報と対応アルゴリズムを表示する
  - 備考： `--verbose` も指定することでアルゴリズムの番号も表示する

    $ gpg --version

- 表示の詳細さを上げる（`-v`）
  - 備考：複数回指定すると詳細さがもっと上がる

    $ gpg --verbose

- 鍵サーバへのアクセスを無効化する
  - 衝突：鍵サーバ関連コマンド（`--recv-keys` や `--send-keys` など）

    --disable-dirmngr

- データを出力する際、 base64 符号化で出力する（`-a`）

    --armor

- 鍵生成や鍵編集の際、オプションやアルゴリズムをもっと表示する

    --expert

- ホームディレクトリを指定する

    --homedir <directory>

- OpenPGP データ（メッセージ、署名、鍵など）のパケットを表示する

    $ gpg --list-packets [--list-only] <data>

- GnuPG の全てのコマンド・オプションを表示する

    $ gpg --dump-options

# 推奨一覧

本ガイドの推奨はあくまでも一般的な推奨だけです。 OpenPGP 利用者が自身の状況や脅威モデルに適した選択・判断をしてください。

## GnuPG 環境設定

GnuPG の動作は 3 つの環境設定ファイルによって左右されます。

- `gpg.conf`： GnuPG の公開鍵操作、メッセージ操作などほとんどの設定。（実行ファイル `gpg` 関連）
- `gpg-agent.conf`： GnuPG の秘密鍵、パスワードなどの秘密に関する操作の設定。（実行ファイル `gpg-agent` 関連）
- `dirmngr.conf`：鍵サーバへのアクセスに関する設定。（実行ファイル `dirmngr` 関連）

GnuPG のコマンドとオプションは全て `--` で始まるが、環境設定ファイルに入れる際に先頭の `--` を省きます。 `#` で始まる行はコメントとして解釈され、 GnuPG に無視されます。

一部の環境設定は生成した OpenPGP データに反映するため、環境設定には指紋（身元特定手がかり）漏れのリスクが伴います。本セクションに推奨する設定は指紋漏れへの完全防止のためではないが、 Tails のデフォルトや他の参考資料から引用したよく使用される設定が多く、推奨から逸れたらより独特な指紋漏れにつながる可能性があります。互換性、メタデータや指紋漏れ、セキュリティなどを考慮しながら、環境設定を慎重に選ぶよう注意してください。また、環境設定のカスタマイズを必要最小限にした方がいいでしょう。

一部の設定は既にデフォルトなため不要かもしれないが、古い GnuPG クライアントを使用している人にとって、または古い GnuPG クライアントを使用する必要があった場合に備えて入れたままにしてもいいかもしれません。

### gpg.conf

- OpenPGP データを出力する際、コメントとバージョン情報の出力を抑える
  - 理由：指紋（身元特定手がかり）漏れを防止する

    no-comments
    no-emit-version

- UTF-8 を使用する

    display-charset utf-8
    utf8-strings

- ファイルを上書きする前に、利用者に確認する
  - 理由：不意のファイル上書きを防止する

    interactive

- GnuPG の実行に安全なメモリの確保を必要とする（確保できなかった場合に実行しない）

    require-secmem

- Verbose モードを設定しない
  - 理由：詳細表示を有効化する他のオプションが推奨となっている
  - 理由： verbose モードを悪用した攻撃は過去にあった
  - 備考：この行を追加せずに `verbose` 行を削除すればよい

    #verbose
    no-verbose

- 署名機能のある副鍵に主鍵と副鍵を結びつける副鍵からの鍵署名を必要とする
  - 鍵署名

    require-cross-certification

- 鍵を生成したり UID を追加したりする際、自由な UID 文字列を許可する
  - 理由：メールアドレス指定などの強制を無効化する
  - UID

    allow-freeform-uid

- 公開鍵を表示する際、全ての鍵の鍵指紋、鍵輪、鍵信用、鍵機能と鍵 ID も表示する
  - 公開鍵

    with-fingerprint
    with-fingerprint
    list-options show-keyring
    list-options show-uid-validity
    list-options show-usage
    keyid-format long

- 鍵をエクスポートする際、最小化した鍵をエクスポートする（最新の自己署名以外の全ての鍵署名を削除する）
  - 理由：鍵署名のソーシャルグラフ情報の流出を防止する
  - 備考：鍵署名もエクスポートしたい場合、 `--export-options no-export-minimal` で取り消す
  - 鍵署名と信用の管理・活用

    export-options export-minimal

- 推奨の優先特徴リストを指定する
  - 理由：指紋（身元特定手がかり）漏れを防止する
  - 理由：他人に強力なアルゴリズムを優先してもらう
  - 優先特徴リスト

    default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed

- 推奨のアルゴリズムを優先する
  - 理由：指紋（身元特定手がかり）漏れを防止する
  - 理由：強力なアルゴリズムを優先する

    personal-cipher-preferences AES256 AES192 AES CAST5
    personal-digest-preferences SHA512 SHA384 SHA256 SHA224
    personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed

- s2k パラメータとアルゴリズムを指定する
  - 理由：パスワードに対する攻撃を防止する
  - 備考： `s2k-cipher-algo` と `s2k-digest-algo` はそれぞれ AES256 と SHA512 に対応していないクライアントに問題を発生させるおそれがあるため、再考の余地がある
  - 鍵ストレッチング

    s2k-mode 3
    s2k-count 65011712
    s2k-cipher-algo AES256
    s2k-digest-algo SHA512

- 脆弱なアルゴリズムを無効化・拒否する
  - 理由：暗号解読のリスクを回避する
  - 備考：多くの鍵はまだ SHA-1 を使用しているため、 `SHA1` の指定には再考の余地がある
  - 備考： `--allow-weak-digest-algos` で `weak-digest` の効果を取り消す

    disable-pubkey-algo DSA
    disable-pubkey-algo ELG
    disable-pubkey-algo ELG-E
    disable-cipher-algo 3DES
    disable-cipher-algo BLOWFISH
    disable-cipher-algo IDEA
    disable-cipher-algo TWOFISH
    weak-digest MD5
    weak-digest RIPEMD160
    weak-digest SHA1

- 圧縮強度を最大に設定する
  - 圧縮

    bzip2-compress-level 9
    compress-level 9

- メッセージに関する MDC （変更検出コード）の使用を強制する
  - 備考： 2.2.8 以降ではデフォルト

    force-mdc

- OpenPGP データを生成時に埋め込みファイル名を空白にし、受信時に埋め込みファイル名を無視する
  - 理由：不意のファイル上書きを防止する
  - 理由：埋め込みファイル名のメタデータ漏れを防止する
  - 理由：埋め込みファイル名の脆弱性を活用した攻撃を防止する
  - 備考： `set-filename` の後に二重引用符が二文字： `""`
  - 埋め込みファイル名

    set-filename ""
    no-use-embedded-filename

- 公開鍵暗号化を行う際、全受信者を匿名化する
  - 理由：受信者の鍵 ID 漏れを防止する
  - 備考： `--no-throw-keyids` で取り消す
  - 暗号化

    throw-keyids

- 署名を行う際、 署名者の UID 文字列を署名に埋め込まない
  - 理由： UID メタデータ漏れを防止する

    disable-signer-uid

- 鍵サーバへのアクセスを無効化する
  - 理由：インターネットへのデータ漏れを防止する
  - 衝突：鍵サーバ関連コマンド（`--recv-keys` や `--send-keys` など）
  - 鍵サーバ

    disable-dirmngr

- 鍵輪に存在しない公開鍵の自動検索・入手を無効化する
  - 理由：インターネットへのデータ漏れを防止する
  - 鍵サーバ

    no-auto-key-locate
    no-auto-key-retrieve

- 署名検証をする際、署名を発行した公開鍵の UID の信用を表示する
  - 理由：検証時に署名鍵信用を確認できるようにする
  - 署名検証

    verify-options show-uid-validity

- 信用モデルを直接信用に設定する
  - 衝突： `trust-model pgp`
  - 鍵署名と信用の管理・活用

    trust-model direct

- 信用モデルを信用の輪に設定する
  - 衝突： `trust-model direct`
  - 鍵署名と信用の管理・活用

    trust-model pgp

### gpg-agent.conf

- キャッシュのデフォルト時間と最長時間をそれぞれ 20 秒と 60 秒に設定する
  - 理由：キャッシュの時間をデフォルトより短くする
  - 備考： 20 秒と 60 秒はただ一例で推奨値ではない

    default-cache-ttl 20
    max-cache-ttl 60

### dirmngr.conf

- Tor 経由で鍵サーバへアクセスする
  - 理由：インターネットへのデータ漏れを軽減する
  - 備考：鍵サーバを使用しない場合、この行を追加しなくても良い
  - 鍵サーバ

    use-tor

- `keys.openpgp.org` の鍵サーバ（オニオンサービス）を指定する
  - 理由： SKS ではなく公開鍵の編集・削除ができる鍵サーバを使用する
  - 備考：鍵サーバを使用しない場合、この行を追加しなくても良い
  - 鍵サーバ

    #keyserver hkps://keys.openpgp.org
    keyserver hkp://zkaan2xfbuxia2wpf7ofnkbz6r5zdbbvxbunvp5g2iebopbfc4iqmbad.onion

## GnuPG 使用慣行

### 指紋やメタデータ漏れの最小化

関連セクション：メタデータをほぼ全く保護しない | オプション、対応アルゴリズム、悪特徴、安全でないデフォルト

- OpenPGP データ（メッセージ、鍵、署名など）を送信する前に、独特な指紋やセンシティブ情報が入っていないことを確認する

- OpenPGP の媒体となる下部システムのメタデータに用心する
  - 備考：例えば、 E2EE メッセンジャー、 HTTP、 TCP/IP、ファイルシステム、バージョン管理システム

- ネットワークを使用する時に、匿名化ネットワーク（例えば Tor）、 VPN、 プロキシなどで接続する
  - 理由：ネットワーク監視から IP アドレスなどの情報を保護する

### 鍵管理

関連セクション：鍵管理

- 秘密鍵を自分で独占的かつ安全に保管する
  - 理由：前方秘匿性がないため、秘密鍵の危殆化は壊滅的

- 主鍵の秘密鍵をオフラインのデバイスに保管する
  - 理由：主鍵の秘密鍵が危殆化すると所有者のなりすましが可能になる
  - 備考：頻繁に副鍵を移行することが不便になる
  - 備考：鍵署名や信用の輪を積極的に使用することが不便になる
  - 備考：有効期限内に鍵編集や鍵署名をしないと予想する場合、主鍵の秘密鍵を削除しても良いかもしれない

- 失効証明書をオフラインのデバイスに保管する
  - 理由：失効証明書が危殆化すると入手者が勝手に自分の鍵を失効させることができる
  - 備考：失効証明書を紙に印刷して保管することも提案されている

- 定期的に鍵全体を移行する
  - 理由：署名鍵が危殆化すると所有者のなりすましが可能になる
  - 理由：前方秘匿性がないため、復号化鍵の危殆化は壊滅的
  - 理由：同じ鍵を長期間使用したら、活動が追跡されやすくなる
  - 備考：鍵移行頻度は 1 年間から 5 年間の間が適切だろうが、使用頻度、使用事例や脅威モデルに応じて合わせる
  - 備考：鍵署名や信用の輪を積極的に使用することが不便になる
  - 備考：鍵全体の移行は、新しい鍵への署名、古い鍵の失効、公開鍵の配布、鍵指紋の通知などの手間がかかるため不便で、古い鍵に蓄積した鍵署名を新しい鍵に持ち越せないため、鍵全体を頻繁に移行しなくても良い

- 頻繁に副鍵を移行する（鍵データを頻繁に使い捨てる）
  - 理由：署名鍵が危殆化すると所有者のなりすましが可能になる
  - 理由：前方秘匿性がないため、復号化鍵の危殆化は壊滅的
  - 備考：鍵移行頻度は 6 ヶ月から 2 年間の間が適切だろうが、使用頻度、使用事例や脅威モデルに応じて合わせる
  - 備考：鍵署名や信用の輪を積極的に使用することが不便になる

- 鍵の有効期限を無期限のままにせず、鍵移行頻度に応じて設定する
  - 理由：鍵が放棄または失効不可能になっても自動的に切れるように
  - 備考：主鍵の秘密鍵を持っている限り、鍵の有効期限をいつでも自由に変更できる

- 主鍵に鍵署名だけの機能だけを与える
  - 理由：複数の機能が付いている主鍵をオフライン保存するとその鍵の鍵署名以外の機能も使えなくなるため、暗号化やメッセージ署名の機能を副鍵に任せる

- 各機能を一つの有効な鍵（主鍵または副鍵）だけに与える
  - 理由：ある機能（例えばメッセージ署名）が複数の鍵に付いている場合、操作を実行する時に実際にどの鍵が使われるかがわからなくなる

- 鍵生成の際、安全かつ適切な公開鍵アルゴリズムを選ぶ
  - 備考：主鍵の公開鍵アルゴリズムを変更したり主鍵だけを移行したりできないため、主鍵にとっては特に重要
  - 備考：現在は一般的に “Curve25519” 楕円曲線暗号（`ed25519` と `cv25519`）を推奨するが、互換性のために RSA を選んでも良い

- 後方互換性を無視し、脆弱なアルゴリズムをできるだけ拒否・回避する
  - 理由：脆弱なアルゴリズムによる OpenPGP の危殆化を避ける
  - 備考：遠い過去に生成された鍵が脆弱な公開鍵アルゴリズムを使用する傾向がある
  - 備考：例えば脆弱な SHA-1 は現在も頻繁に使われていて、この推奨の徹底が無理かもしれない

- 鍵の失効・移行を主要連絡相手に通知するための手段を確保する
  - 理由：鍵の紛失・危殆化に伴って通信手段がなくなるかもしれない
  - 備考：どの通信経路・媒体が適切か、目立たない信号手段が必要か、チャレンジ・レスポンス認証を行うか、相手がどうやって新しい公開鍵を入手・検証するかなどを考える

### 鍵サーバと鍵配布

関連セクション：鍵サーバ

- 自分の公開鍵を本当に公開したいか考える
  - 理由：敵が公開鍵を知ったら、自分の活動の追跡などが可能になる
  - 理由： UID 内の連絡先などのセンシティブ情報の公開を避ける
  - 理由：誰でもが勝手に公開鍵を SKS にアップロードできる

- SKS に公開鍵をアップロードしない
  - 理由：一度でも SKS にアップロードされたら取り返しがつかない
  - 備考： SKS は付加専用（編集・削除不可能）で非認証の鍵サーバで、誰でもがデータベースの検索が容易にできる

- 公開鍵を公開せず、安全な通信経路で連絡相手に配布する
  - 理由： SKS への勝手なアップロードの可能性を最小限にする
  - 理由：自分の鍵の存在の秘匿化、否認可能な鍵交換などを実現する
  - 備考：特定の活動・用途のために生成した鍵に適切かもしれないが、自分の公開連絡先として生成した鍵にとって不適切

- 自分が管理・支配する媒体で公開鍵を配布する
  - 備考：例えば、自分のウェブサイトやアカウントのプロフィール
  - 備考：鍵サーバを使いたくない場合

- アップロード認証を必要とし、公開鍵の編集と削除が可能な鍵サーバで公開鍵を配布する
  - 備考：例えば、 `keys.openpgp.org`
  - 備考：自分が管理・支配する媒体での配布の代わりに

- GnuPG で定期的に公開鍵を更新したい場合、プライバシー保護を目的とした Parcimonie を使用してみる
  - 理由：鍵サーバからの公開鍵の更新をプライベートにする
  - 備考： Parcimonie は Tor 経由で鍵サーバに接続し、無作為の時間で無作為に公開鍵を更新するらしい
  - 備考：アリスとボブは個人的に Parcimonie を使ってみたことがない

### 鍵署名と信用

関連セクション：鍵署名 | 信用

- 信用の輪に頼るコミュニティに参加していない限り、鍵署名と信用の輪を積極的に参加しなくても良い

- 直接信用または信用の輪のうちどちらの信用モデルを使用するかを決め、信用モデルの指定を環境設定ファイルに追加する

- 鍵署名を発行するつもりがないが信用の輪を使用する場合、エクスポートに制限がかかるローカル署名を活用する
  - 理由：エクスポートの際の不意なソーシャルグラフ漏れを防ぐ
  - 備考：鍵署名と信用の輪を積極的に参加しなくても、ローカル署名と信用の輪を公開鍵の鍵信用の評価に使用できる

- 鍵署名の発行を目的に、対面なしに他人の公開鍵を検証する際、認証付き公開情報、相手とのチャレンジ・レスポンス認証、信用の輪などの必要な確認手段を使用する
  - 理由：相手の公開鍵は本当に相手が支配するものであることに自信を得るまで、その公開鍵に署名すべきではない

- 他人の公開鍵に署名した後、鍵サーバにアップロードせず、直接その人に署名した公開鍵を安全に送る
  - 理由：相手に鍵サーバへのアップロードを任せる
  - 理由：鍵サーバへのアップロードはドクシング行為に当たる

### 電子メール

注：一部の推奨を一般化するとメール以外の通信手段にも適用できます。

関連セクション：注意点と限界

- 電子メールより、より安全な通信手段を優先する
  - 理由： OpenPGP メールより理解と使用が簡単な E2EE が存在する
  - 理由：電子メールは暗号化を強制しないため、平文が漏れる可能性が高い
  - 理由：電子メールにはメタデータ、改竄、なりすましなどの問題がある
  - 理由：メールを暗号化しても暗号文の盗聴・収集が可能で、 OpenPGP 関連のメタデータ漏れや前方秘匿性の欠如も考えるべき

- メールの差出人、宛先、送受信日時、時間帯、クライアント、 OS、 IP アドレスなどのメタデータに要注意

- Bcc 欄の宛先のプライバシー保護を信用しない
  - 理由： Bcc 欄に記載された宛先を漏らすメールのクライアントやサーバがある
  - 備考： Bcc の保護が健全だとしても、 OpenPGP データに鍵 ID や鍵指紋が埋め込まれないよう `--throw-keyids` を使用する必要がある

- メールの件名を無意味の文字列にする
  - 理由：メタデータ漏れを回避する
  - 備考：例えば、空白、一つの半角スペース、 `...` 省略符号

- メールクライアントの OpenPGP 機能の代わりに、オフラインのテキストエディタと GnuPG を使用する
  - 理由：メールクライアントの OpenPGP 機能の実装に多く問題がある
  - 理由：平文と秘密鍵をインターネットに接するソフトウェアから切り離す
  - 理由： OpenPGP メールクライアントが強制する UID 形式を回避する
  - 備考：この推奨では PGP/MIME が使用できないかもしれない
  - 備考：メールクライアントの OpenPGP 機能より不便で、多数の OpenPGP メールを扱うには無理があるかもしれない

- OpenPGP メールクライアントを使用する場合、安全なメールクライアントを検討・採用する

- メールクライアントの OpenPGP 機能を有効化した場合、暗号化が強制されることを確認する
  - 理由：不意な平文送信を防止する
  - 備考：相手側のクライアントが暗号化を強制しないかもしれないことを考慮すべき

- メールクライアントまたはメールサーバに下書きを保存しない
  - 理由：平文をメールネットワークに漏らすリスクを回避する

- クライアントが添付ファイルを暗号化するかを確認するか、ファイルを GnuPG で暗号化してから添付する
  - 理由：添付ファイルの平文をメールネットワークに漏らすリスクを回避する
  - 備考：添付ファイルを GnuPG で暗号化してメールの本文にコピペするという方法もある

- メールに返信する際、本文から前のメールの内容を削除し、引用したい場合に引用したい部分だけを残す
  - 理由：前のメールの内容を漏らす機会を最小限にする

- メッセージに署名すればメッセージが否認不可能になる一方、署名しなければ相手がメッセージを信用しないかもしれないため、すべての送信メッセージへの（自動）署名の可否について考える
  - 備考：署名の代わりに否認可能な完全性・認証保護手段（例えば MAC）が使えると理想的

- 受信、送信、下書き、ゴミ、迷惑メールなどのメールボックスをすべて空にした状態を維持する
  - 理由：メールサーバによる覗き見の機会を最小限にする
  - 備考：この推奨は使用事例次第で無理があるかもしれず、デバイス上でのデータの保管に伴う不便さやリスクも考慮すべき

- 連絡先リストをメールサーバに保存しない
  - 理由：メールサーバへのソーシャルグラフ情報の流出を最小限にする
  - 備考：この推奨は使用事例次第で無理があるかもしれず、デバイス上でのデータの保管に伴う不便さやリスクも考慮すべき

インラインと添付ファイルの両方を個別の OpenPGP データとして本文に入れた場合のメールの例（送信前）

    From: Alice <alice@example.org>
    To: Alice <alice@example.org>
    Bcc: Bob <bob@example.org>
    Subject: ...

    -----BEGIN PGP MESSAGE-----

    D290tRvIZsNv7lKDVIl+OBa8eITgNGz61L0IbjdTd0MrfSeg+H1CUZIbbH+E6kq0
    KSwc/5gZ1JcGBJqpDZFDqG6BD0PzcIlnHrUrtdPLlmM68TaBZHDZAFtfkBAM8Nwk
    kixmj9H3/oRJPY3im7i6A1gJ3Gen2k0sp9IkGUy87WWfTyQxzt66TqZgrTMJ8fWg
    GHoGoe1J9Neaz8k=
    =GIwg
    -----END PGP MESSAGE-----

    -----BEGIN PGP MESSAGE-----

    bja/tnS5D5HguFmgA1Vi9PwaVydMFdErl1OZTsFLhbGnnxwVAJ6Fm8WGCCDQME60
    b5oQ7/mx2rfWyzpzVOi4P3cQPZDvQsORh+D75CSI+izscPDvzciMAzxEfeoFyGM+
    MYmr2E6c2p6hASpI5K3CzaNjmWii8fCK9OgaLXUmU5xSYHY93IaxZOSDzL5p7C8+
    nTZKiiGm7srnc3iZnBNvQxODvlBG7BHYOejlRU1wVX2jB4kI7wBDnI/d/nA5/bS1
    F9DiLRgdt/0aOMSu+h40Hk09tSlOJzS2pEu7L3BpLwaZTv5AbEnJtPkzlxEB2tdc
    lkUwBTNG5MImOe724I8mvfVj9W9wVNdTvNIZpFpCEj/gayGkNHSw3RqOWglMm6UK
    PlsDnI5AjHxVAX0kjtE4xAREPNtQlhPWXQHKnaXfLCdZrqwUly2zPI1pF18oVr4h
    u+giH9YIMc7wLjZWkiMiCiOBDKqdQ71T8U9YZ20SwwrsVwx9m29S4CbjxWmvw/I6
    tNvy292/FLaBujSP7G8j08hKYqCvM4Eq2rCxTuaKO7VGUeucJS780TNT7CbxoojW
    8fS3lISQK3XrSZ7afQFGXUvq6KutA8HuIKZGll52/hCD6ZVSFj0u4YDczpeJxBzE
    J7h9kBxb/yFhkPcyUlMc
    =Qu/C
    -----END PGP MESSAGE-----

# 付録

## よく使われるアルゴリズム

公開鍵アルゴリズム

識別子*1 | アルゴリズム系 | 識別子*2 | パラメータ | 対応鍵機能*3
--- | --- | --- | --- | ---
18 | ECDH | `cv25519` | Curve25519 曲線 | E
22 | EdDSA | `ed25519` | Ed25519 曲線 | C S A
1 | RSA | `rsa4096` | 4096 ビット | C E S A
1 | RSA | `rsa3072` | 3072 ビット | C E S A
1 | RSA | `rsa2048` | 2048 ビット | C E S A

- *1： `--list-packets` や `--verbose --version` に表示される。
- *2：鍵表示時に `pub` や `sub` などの後に表示される。
- *3：鍵機能を参照。

サイファ、ハッシュ関数と圧縮関数

識別子*1 | 識別子*2 | アルゴリズム | 種類
--- | --- | --- | ---
`S9` | `AES256` | AES-256 | サイファ
`S8` | `AES192` | AES-192 | サイファ
`S7` | `AES` | AES-128 | サイファ
`S3` | `CAST5` | CAST5・CAST-128 | サイファ
`H10` | `SHA512` | SHA-512 | ハッシュ関数
`H9` | `SHA384` | SHA-384 | ハッシュ関数
`H8` | `SHA256` | SHA-256 | ハッシュ関数
`H11` | `SHA224` | SHA-224 | ハッシュ関数
`Z2` | `ZLIB` | zlib | 圧縮関数
`Z3` | `BZIP2` | bzip2 | 圧縮関数
`Z1` | `ZIP` | ZIP | 圧縮関数
`Z0` | `Uncompressed` | 無圧縮 | 圧縮関数

- *1： `--edit-key` コマンド内の `setpref` サブコマンドに使用。 `--list-packets` や `--verbose --version` に表示される。
- *2： `--default-preference-list` コマンドに使用。

## よくある署名種類

sigclass*1 | 署名種類 | 発行鍵 | ハッシュ化対象 | 備考
--- | --- | --- | --- | ---
0x00 | バイナリメッセージ署名 (binary message signature) | メッセージ署名機能のある鍵 | バイナリメッセージ | 標準署名と分離署名のデフォルト。
0x01 | テキストメッセージ署名 (text message signature) | メッセージ署名機能のある鍵 | CRLF 改行変換されたメッセージ | クリア署名に必ず使用される。
0x10 | 検証度不明の証明書保証 (generic certification) | 保証者の主鍵 | 保証対象 UID*2 | デフォルトの非自己署名種類。
0x11 | 検証なしの証明書保証 (persona certification) | 保証者の主鍵 | 保証対象 UID*2 |
0x12 | 簡易検証済みの証明書保証 (casual certification) | 保証者の主鍵 | 保証対象 UID*2 |
0x13 | 確信検証済みの証明書保証 (positive certification) | 保証者の主鍵 | 保証対象 UID*2 | 自己署名にも用いられる。
0x18 | 副鍵の主鍵への結びつけ (subkey binding) | 結びつけ対象主鍵 | 主鍵と副鍵の公開鍵データ |
0x19 | 主鍵の副鍵への結びつけ (primary key binding) | 結びつけ対象副鍵 | 主鍵と副鍵の公開鍵データ | メッセージ署名機能のある副鍵だけに関する。 0x18 署名に埋め込まれる。
0x20 | 鍵全体の失効 (key revocation) | 失効対象鍵自体または失効権限を与えられた鍵 | 失効対象主鍵の公開鍵データ |
0x28 | 副鍵の失効 (subkey revocation) | 結びつけをした主鍵または失効権限を与えられた鍵 | 失効対象副鍵の公開鍵データ |
0x30 | 証明書保証の失効 (certification revocation) | 保証発行鍵または失効権限を与えられた鍵 | 失効対象 UID |

- *1： `--list-packets` が署名情報を表示する時に表示される。
- *2：署名者が UID を指定するが、ハッシュ化の対象について文書化されていない。

## よくある OpenPGP データのパケット種類

tag*1 | パケット | 備考
--- | --- | ---
1 | 公開鍵暗号化されたセッション鍵 (public key encrypted session key) |
2 | 署名 (signature) | 詳しくはよくある署名種類を参照。
3 | パスワード暗号化されたセッション鍵 (symmetric key encrypted session key) | 公開鍵暗号化も同時に使用された場合、パスワードで保護されたセッション鍵も含む。
4 | 署名ヘッダ (one-pass signature header) | 受信クライアントでの単一通過処理を可能にする。
5 | 秘密鍵の主鍵 (private primary key) | 公開鍵データも含む。
6 | 公開鍵の主鍵 (public primary key) | 証明書の始まりを示す。
7 | 秘密鍵の副鍵 (private subkey) | 公開鍵データも含む。
8 | 圧縮データ (compressed data) |
11 | 平文データ (literal data) |
13 | UID (user ID) |
14 | 公開鍵の副鍵 (public subkey) |
17 | 拡張 UID (user attribute) |
18 | MDC 保護付きセッション鍵暗号化されたデータ (session key encrypted MDC protected data) |
63 | （不明な GnuPG パケット） | クリア署名されたメッセージに使用。

- *1： `--list-packets` がパケット情報を表示する時に表示される。

## 公開鍵アルゴリズムのサイズと生成時間の比較

アルゴリズム | 生成時間 | 公開鍵サイズ | 分離署名サイズ
--- | --- | --- | ---
`ed25519` | 2.17 秒 | 498 バイト | 119 バイト
`rsa1024` | 2.24 秒 | 865 バイト | 181 バイト
`rsa4096` | 10.57 秒 | 2789 バイト | 566 バイト

共通の条件や値

- 1 つの 3 文字の UID
- 主鍵の鍵機能を鍵署名（Certify）だけに
- 1 つの副鍵を生成し、鍵機能をメッセージ署名（Sign）だけに
- base64 符号化を使用せず
- 0 バイトのメッセージに分離署名
- 優先特徴リストや他の公開鍵メタデータ

## 信用の輪の解説

Alice による所有者信用の指定

- Alice は Bob からの鍵署名を完全に信用する。
  - 完全鍵信用の成立には完全信用された 1 人以上からの鍵署名が必要。
- Alice は Carol、 Dave と Ellen からの鍵署名を不完全に信用する。
  - 完全鍵信用の成立には不完全信用された 3 人以上からの鍵署名が必要。
- 他の人の鍵署名は信用されない。

鍵信用の評価

- Alice は Bob、 Carol、 Dave と Ellen の公開鍵を直接信用する。
  - Alice 自身の鍵署名によって Bob、 Carol、 Dave と Ellen の公開鍵は完全信用される。
- Bob は Frank の公開鍵を直接信用する。
  - 完全信用されている Bob の鍵署名によって Frank の公開鍵は完全信用される。
- Carol と Dave は Grace の公開鍵を直接信用する。
  - 不完全信用されている 2 人の鍵署名によって Grace の公開鍵は不完全信用される。
- Carol、 Dave と Ellen は Heidi の公開鍵を直接信用する。
  - 不完全信用されている 3 人の鍵署名によって Heidi の公開鍵は完全信用される。
- Frank は Isaac の公開鍵を直接信用する。
  - 信用されていない Frank の鍵署名によって Isaac の公開鍵は信用されないまま。

信用の輪関連パラメータ

    # 信用モデルの指定
    trust-model pgp
    # 完全鍵信用の成立のために必要な完全鍵署名の数
    completes-needed 1
    # 完全鍵信用の成立のために必要な不完全鍵署名の数
    marginals-needed 3
    # 考慮される鍵署名連鎖の最大の深さ
    max-cert-depth 5

1. Phil Zimmermann, PGP Source Code and Internals. MIT Press (1995). ISBN 0-262-24039-4↩︎

2. MIME （Multipurpose Internet Mail Extensions）：電子メールの形式拡張（ASCII 以外の文字セット、添付ファイルなど）を指定するインターネット標準。↩︎

3. E2EE （エンドツーエンド暗号化）：送信者と受信者で構成される当事者（エンドポイント）だけが鍵を持ち、中間者や第三者による傍聴を防ぐ暗号化。↩︎

# アリスとボブ

ガイド一覧に戻る — Markdown | HTML

## 連絡先

### PGP 鍵

`1D3E 313C 4DB2 B3E0 8271 FC48 89BB 4CBB 9DBE 7F6D`

- ウェブサイト上： `https://git.disroot.org/alice2bob/alice2bob/src/branch/master/alice2bob.asc`
- 鍵サーバ（クリアネット）： `https://keys.openpgp.org/search?q=1D3E313C4DB2B3E08271FC4889BB4CBB9DBE7F6D`
- 鍵サーバ（オニオン）： `http://zkaan2xfbuxia2wpf7ofnkbz6r5zdbbvxbunvp5g2iebopbfc4iqmbad.onion/search?q=1D3E313C4DB2B3E08271FC4889BB4CBB9DBE7F6D`

### ウェブサイト

`https://git.disroot.org/alice2bob/alice2bob`

## 検証

`https://git.disroot.org/alice2bob/alice2bob/src/branch/master/verify.md`

## 免責事項

アリスとボブはセキュリティ専門家でも法律家でも金融アドバイザーでも医師でもありません。本シリーズの目的はあくまでも情報提供で、何の助言でもありません。本シリーズは全くの無保証で提供されます。本シリーズによってどんな不利、損失または損害が生じても、アリスとボブは一切の責任を負いません。ご自身の状況を考慮し、自己責任で本シリーズを使ってください。