gpgコマンドの使い方

[前回の投稿](https://qiita.com/kanatatsu64/items/85104644d1599c244f35)から、さらにGPGについて調べたので共有します。内容が多いので、説明は必要最低限にします。

gpg(GnuPG)は、OpenPGP(Pretty Good Privacy)\*のGnu実装です。(\* RFC4880)

# web of trust

SSLではchain of trustで信頼関係を構築しますが、PGPではweb of trustという方法で、信頼関係を構築します。

web of trustでは、validとtrustという似て非なる二つの概念を用います。また、それらをつなぐものとして、signがあります。

<dl>
    <dt>valid</dt>
    <dd>
        対象: key+uidの組<br/>
        種類: unknown、marginal、full<br/>
        意味: key+uidの身元は保証されている
    </dd>

    <dt>trust</dt>
    <dd>
        対象: key<br/>
        種類: none、unknown、marginal、full、ultimate<br/>
        意味: keyの管理者(owner)はきちんとした判断能力を有している
    </dd>

    <dt>sign</dt>
    <dd>key+uidの身元を保証すること</dd>
</dl>

none trustとunknown trustに違いはありませんが、noneとすることでtrustできないという判断をしたことを明示できます。

full trustとultimate trustに違いはありません(多分)が、ultimateは自分が作ったkeyにのみ適用するようにします。また、自分が作ったkeyはデフォルトでultimate trustとなっています。

key+uidがfull validであるための条件は、

- key+uidをsignしている
- key+uidが3つ以上のmarginalのkeyにsignされている

です。どちらかを満たせばvalid(full valid)となります。一方、

- key+uidが1つまたは2つのmarginal trustなkeyにsignされている

場合には、marginal validとなります。

web of trustの例は、[Using trust to validate keys](https://www.gnupg.org/gph/en/manual/x334.html#AEN384)を見てください。

# pub keyとsub key

PGPは公開鍵暗号を用います。そのため、使用される鍵は、秘密鍵と公開鍵のpairです。以下、鍵のpairを単に鍵といいます。

鍵pairには、pub keyとsub keyの二種類があります。pub keyが一番重要な鍵で、sub keyはpub keyに紐づけられた鍵です。pub keyが重要なのは、pub keyがあればsub keyをいくらでも作ることができるからです。

```
pub key <- sub key1
        <- sub key2
        ...
```

pub keyと公開鍵(public key)は別の概念なので、注意してください。また、pub keyはmaster keyと呼ばれることもあります。

# keyserver

gpgコマンドを使ってローカルで作った公開鍵を公開するには、keyserverを利用します。keyserver同士は同期しているので、一つのkeyserverにアップロードするだけで良いです。また、当然ながら、keyserverにuploadされるのは公開鍵だけです。

keyserverに一度uploadしたものを削除することはできません。その場合は、revokeを使用してください。

# コマンド操作

以下の説明で、

```shell
gpg> ...
```

となっている部分は、

```shell
gpg --edit-key <key-id>
```

で対話モードに入った後の状態を意味しています。

対話モードを終了するときは、

```shell
gpg> save
```

で、変更を保存してください。(trustを除く)

# 設定ファイル

gpgの設定ファイルは、`~/.gnupg/gpg.conf`です。

```:~/.gnupg/gpg.conf
<option> <value> <value> ...
```

\* \<option\>: ロングオプションの`--`を省略したもの

コマンドでも指定した場合、コマンドのオプションが優先されます。以下、コマンドのロングオプションにデフォルト値を設定したいときは、このファイルに書いてください。

# keyserverに対する操作

使用するkeyserverは、コマンドのオプションで指定することができます。

```shell
gpg --keyserver <url>
```

- 鍵の公開

```shell
gpg --send-keys <key id> <key id>
```

- 鍵の取得

```shell
gpg --recv-key <key-id>
```

- 鍵の検索

```shell
gpg --search-key <key-id>
```

# key操作

- keyring内の鍵を表示

```shell
# 公開鍵keyring
gpg --list-keys
# 秘密鍵keyring
gpg --list-secret-keys
```

秘密鍵を持っていない場合、`gpg --list-secret-keys`の結果は、

```
sec#  rsa3072 2019-01-29 [SC] [expires: 2020-01-29]
      AEE26A5E89D476DC5A8195132DD30C64EC41FA6B
uid           [ultimate] hogehoge <hogehoge@example.com>
```

のように、`sec`の後に`#`が付いて表示されます。

## pub key操作

自分が持っている鍵は、ローカルなkeyring(鍵束)にimport(追加)して保管します。

- pub keyの作成

```shell
# 簡単バージョン
gpg --gen-key
# 詳しく設定
gpg --gen-full-key
```

- pub keyのimport(ファイルから)

インターネット等から得たpub keyをkeyringに追加するには、

```shell
# 公開鍵/秘密鍵
gpg --import <key file>
```

とします。

- pub keyのexport

```shell
# 公開鍵
gpg [--armor] [--output <file>] --export-keys <key-id>
# 秘密鍵
gpg [--armor] [--output <file>] --export-secret-keys <key-id>
```

armorを省略した場合は、バイナリ形式で出力されます。
outputを省略した場合は、標準出力に出力されます。

- pub keyの削除

```shell
# 秘密鍵を持っている場合、先に消しておく
gpg --delete-secret-keys <key-id>
gpg --delete-keys <key-id>
```

- pub keyのrevoke

```shell
# pub keyのrevoke用鍵の作成
gpg --gen-revoke <key-id> --outfile <file>
# pug keyのrevoke
gpg --import-key <file>
```

- pub keyの更新

```
gpg --refresh-keys [<key-id>]
```

\<key-id\>を省略した場合は、keyring内の全ての鍵が更新されます。

## sub key操作

- sub keyの追加

```shell
gpg> addkey
```

- sub keyの削除

```shell
gpg> key <key num>
gpg> delkey
```

- sub keyのrevoke

```shell
gpg> key <key num>
gpg> revkey
```

# uid操作

uidはpub keyに対してのみ関連づけられます(多分)。

- uidの追加

```shell
gpg> adduid
```

- uidの削除(鍵をkeyserverにuploadしていないことが前提)

```shell
gpg> uid <user num>
gpg> deluid
```

- uidのrevoke

```shell
gpg> uid <user num>
gpg> revuid
```

- uidに署名

```shell
gpg> uid <user num>
gpg> sign
```

# sign

signはkey+uidの組\*に対して行います。(\* uidがkeyの間で一意でないことに注意)

signを行うユーザーは、`--default-key`オプションまたは`-u`オプションで選択できます。このとき選択できるのは、

- key-id
- uid

で、key+uidの組は選択できないので注意してください。

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">gpgではsignの時には、uidの指定かkeyの指定しかできない。uidを指定したときは、secret keyringからuidを検索して、はじめに見つかったkeyを使うらしい。では、keyを指定した時のuidはどうやって決まるのかな。やっぱり、keyのprimary uidが使われるのか？？<a href="https://twitter.com/hashtag/gpg?src=hash&amp;ref_src=twsrc%5Etfw">#gpg</a> <a href="https://twitter.com/hashtag/signing?src=hash&amp;ref_src=twsrc%5Etfw">#signing</a></p>&mdash; kanatatsu64 (@kanatatsu64) <a href="https://twitter.com/kanatatsu64/status/1090175684134109184?ref_src=twsrc%5Etfw">January 29, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

signには3段階のlevelがあり、

> 
0 means you make no particular claim as to how carefully you verified the key.
</br>
              1  means you believe the key is owned by the person who claims to own it but you could not, or did not verify the key at all. This is useful
              for a "persona" verification, where you sign the key of a pseudonymous user.
</br>
              2 means you did casual verification of the key. For example, this could mean that you verified the key fingerprint and checked the  user  ID
              on the key against a photo ID.
</br>
              3  means you did extensive verification of the key. For example, this could mean that you verified the key fingerprint with the owner of the
              key in person, and that you checked, by means of a hard to forge document with a photo ID (such as a passport) that  the  name  of  the  key
              owner  matches  the  name  in the user ID on the key, and finally that you verified (by exchange of email) that the email address on the key
              belongs to the key owner.
(man gpg(1)より)

です。どのlevelでsignするかは`--default-cert-level`オプションで設定できます。デフォルトは0です。また、`--ask-cert-level`オプションを付けることで、sign実行時にlevelを聞いてくれます。ネットの記事では、このオプションをつけている場合が多いです。

- signの表示

```shell
gpg --list-sigs
# または
gpg --check-sigs
```

- signの追加

uidの選択を省略すると、全てのuidに対してsignされます。

```shell
gpg> uid <user num>
gpg> sign
```

- signの削除

```shell
gpg> uid <user num>
gpg> delsig
uid  hogefuga <hogefuga@example.com>
sig!3        2CDD40C5ECD1FA3B 2019-01-30  [self-signature]
Delete this good signature? (y/N/q)n  #入力
uid  hogefuga <hogefuga@example.com>
sig!         B294B64FD3D54E8B 2019-01-30  piyoo <piyoo@example.com>
Delete this good signature? (y/N/q)y  #入力
```

- signのrevoke

```shell
gpg> uid <user num>
gpg> revsig
You have signed these user IDs on key 1BE140C53CD1FC3B:
     hogefuga <hogefuga@example.com>
   signed by your key 2CDD40C5ECD1FA3B on 2019-01-30
   signed by your key 3A94B64AC3364C8B on 2019-01-30

user ID: "hogefuga <hogefuga@example.com>"
signed by your key 2CDD40C5ECD1FA3B on 2019-01-30
Create a revocation certificate for this signature? (y/N) n #入力
user ID: "hogefuga <hogefuga@example.com>"
signed by your key 3A94B64AC3364C8B on 2019-01-30
Create a revocation certificate for this signature? (y/N) y #入力
```

# trust (ownertrust)

trustはpub keyに対して設定されます。trustはローカル環境(trust-db)に保存されます。

trustには5つのlevelがあります。

>
  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
(gpg> trustの実行結果より)

```shell
gpg> trust
```

# 参考
- web of trust
    - https://www.gnupg.org/gph/en/manual/x334.html#AEN384
- gpg
    - https://www.gnupg.org/gph/en/manual/book1.html
    - [GnuPG](https://www.gnupg.org)
- 前回までの記事
    - [githubで使うGPG鍵の作成](https://qiita.com/kanatatsu64/items/85104644d1599c244f35)
    - [gpg --gen-keyが止まる件について](https://qiita.com/kanatatsu64/items/c6f612b34ec69809fbb6)