GPGについて学んだことを整理してみる


## はじめに
リポジトリからパッケージをインストールする際に，以下の警告が発生して，GPGについて気になったので学んだことを書いてみます．


```console
$ sudo apt-get update

・・・略・・・
W: GPG error: http://cdn-fastly.deb.debian.org/debian stretch Release: The following signatures were invalid: BADSIG 7638D0442B90D010 Debian Archive Automatic Signing Key (8/jessie) <ftpmaster@debian.org>
W: The repository 'http://deb.debian.org/debian stretch Release' is not signed.
・・・略・・・
```
#本稿の構成
* GPG Errorの対処法
* GPGとは
* gpgコマンドのクイックリファレンス

# 「GPG error」の内容と対処
まず初めに,上記警告文の内容と解決方法について記述します.
その後,興味本位でGPGについて知りたかったので,その内容を後述します.

エラーの内容としては，登録されているリポジトリに関する（内容の正当性を保証するための，公開鍵暗号方式による）署名が無効であるというエラーです．エラーが出た署名が正規のものであると確認ができる場合は，以下のコマンドラインで大丈夫です.

#### 署名が正規であると確認できた場合

```
sudo apt-key adv --recv-keys --keyserver hkp://p80.pool.sks-keyservers.net:80 7638D0442B90D010 
```

上記は、インストール対象のパッケージ認証時に利用されるローカル内にある鍵リストに,新たなキー(署名が正規である鍵)を追加しています.
キーの追加手順として,公開鍵が登録されているサーバにアクセスして,登録されている鍵ID(上記では`7638D0442B90D010 `)を指定して追加します.`adv`コマンドを指定することで`gpg`コマンドが呼び出されます.`--recv-keys` とか`--keyserver`は`gpg`コマンドのオプションです.

`--keyserver`には公開鍵が登録されているサーバと鍵IDを指定することで,どこからどの鍵にアクセスするかを指定し,`--recv-keys`により,鍵をインポートしています.

#### 署名が正規であると確認できない場合
署名が正規でないと確認できない場合は，

```console
$ sudo -i　
# apt-get clean
# cd /var/lib/apt
# mv lists lists.old
# mkdir -p lists/partial
# apt-get clean
# apt-get update
```
上記の実行は，まずスーパーユーザとしてインタラクティブシェルを開きます．
`apt-get`からインストールされたファイルは「/var/cache/apt/archives」にキャッシュされていて、アプリを削除した後もキャッシュは残っているので，これらのキャッシュを`apt-get clean`で削除します．その後，`apt-get update`で，パッケージインデックスを更新します．


# GPGとは

通常，Linux環境では自分が意図した作成者が作ったソフトであるか、
使うインストーラーが本物である事を検証（身元が正しいかどうか）してからインストールします．
このとき，ソフトウェアの検証に使用される仕組みの一つがgpgです．

gpgはGNU Privacy Guard (GnuPG, GPG)の略で暗号化ソフトウェアです．
暗号化だけでなく署名や認証といったオンライン上の機密や信用を管理するツールとしても利用されます．特徴として公開鍵暗号方式を使用しますが，その鍵の管理のために，認証局を設置しません．**各利用者の責任**で鍵を管理し，取得した公開鍵をチェックします．

署名は署名でも，鍵に対する署名とファイルに対する署名の二種類の署名があり, 注意が必要です.

## 鍵管理
公開鍵暗号方式では，秘密鍵(プライマリーキー，主鍵)と公開鍵(サブキー，副鍵)の組み合わせで構成されます．これらの鍵の使い分けによって，暗号と署名が行われます．
ファイルに対する暗号化(復号)と署名(検証)の際，鍵の使い分けは以下の通りです．

* 暗号化には，受信者の公開鍵を使用
* 復号には，受信者の秘密鍵を使用
* 署名には，送信者の秘密鍵を使用
* 検証には，送信者の公開鍵を使用


**自身の公開鍵を使って暗号化, 検証する場合, 自身の公開鍵は自身の署名があらかじめされているので問題ないですが, 他人の公開鍵を使って暗号化, 検証する場合, その公開鍵が確かに本人のものであると保証を確認し，署名されていなくてはいけません.**

また，gpgでは，秘密鍵を使用するとき，パスフレーズを入力します．
なので，自分の秘密鍵のパスフレーズを忘れないことと，漏らさないことが大切になります．



## 公開鍵の交換

公開鍵の交換方法としては，手動で行う方法と公開鍵サーバーを利用した交換方法があります．
公開鍵サーバの利用によって，手動で行う方法よりも，スムーズに鍵の交換が可能です．他人の公開鍵に関する情報(ユーザーの名前、メールアドレス、公開鍵のID)が指定でき，`gpg --search-keys`を使用します．


## 公開鍵の正当性

gpgでは，他人と同じユーザIDの鍵ペアを作成することができます．また，ソフトウェアに手を加えれば，鍵IDを同じにすることができ，要するに，偽造鍵が作成される場合があります．
偽造鍵と正しい鍵を区別するために，公開鍵の利用者は事前に公開鍵の正当性を確認する必要があります．確認する手段としては，フィンガープリント(ハッシュ値，指紋)が通常使用されます．取得した公開鍵から求めたフィンガープリントと鍵の所有者が提供するフィンガープリントが一致しているかどうかを確認して正当性を確認します．

正当性の確認が済んだ後，受け取った公開鍵に，自分の秘密鍵で署名することで，以後，安全に利用ができます．

また，個人と個人が鍵の署名を互いに行いあうことで信頼する関係を構築し，それらが連鎖的に複数の信頼関係を構築していくことによって，公開鍵の信頼度を設定することができます．この仕組みはを「信頼の輪」あるいは「信頼の網」と呼ばれます．
ちなみに，信頼関係の仕組みは「信頼の木構造」という仕組みも存在します．PKIは信頼の木構造を利用して，大規模な認証基盤を構築されているといわれています．


# gpgコマンドのクリックリファレンス
`gpg`コマンドの簡単な実装例になります．

## 鍵の生成
鍵の生成手順としては，以下の通りになります．
1.`gpg --gen-key`
2.公開鍵と秘密鍵が書き込まれる二つのファイルが生成(pubring.gpgとsecring.gpg)
3.暗号の種類(アルゴリズム)を選択
4.鍵の有効期限，名前，メールアドレスを設定する
5.秘密鍵を守るために，パスフレーズを二回入力
6.ランダムな鍵(秘密鍵と公開鍵)を生成

以下のその実装例になります．環境はUbuntuです．

```bash

$ gpg --expert --full-gen-key
gpg (GnuPG) 2.2.4; Copyright (C) 2017 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.

ご希望の鍵の種類を選択してください:
   (1) RSA と RSA (デフォルト)
   (2) DSA と Elgamal
   (3) DSA (署名のみ)
   (4) RSA (署名のみ)
   (7) DSA (機能をあなた自身で設定)
   (8) RSA (機能をあなた自身で設定)
   (9) ECC と ECC
  (10) ECC (署名のみ)
  (11) ECC (機能をあなた自身で設定)
  (13) 既存の鍵
あなたの選択は? 1
RSA 鍵は 1024 から 4096 ビットの長さで可能です。
鍵長は? (3072) 1024
要求された鍵長は1024ビット
RSA 鍵は 1024 から 4096 ビットの長さで可能です。
副鍵の鍵長は? (3072) 1024
要求された鍵長は1024ビット
鍵の有効期限を指定してください。
         0 = 鍵は無期限
      <n>  = 鍵は n 日間で期限切れ
      <n>w = 鍵は n 週間で期限切れ
      <n>m = 鍵は n か月間で期限切れ
      <n>y = 鍵は n 年間で期限切れ
鍵の有効期間は? (0) 1m
鍵は2019年10月30日 19時05分56秒 JSTで期限切れとなります
これで正しいですか? (y/N) y

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

本名: gyokoyama
電子メール・アドレス: hogehoge@gmail.com
コメント: create sample gpg-key
次のユーザIDを選択しました:
    "gyokoyama (create sample gpg-key) <hogehoge@gmail.com>"

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

pub   rsa1024 2019-09-30 [SC] [有効期限: 2019-10-30]
      610DC5714D9ECE6B6A62984451BD1BB482F9F00B
uid                      gyokoyama (create sample gpg-key) <hogehoge@gmail.com>
sub   rsa1024 2019-09-30 [E] [有効期限: 2019-10-30]

```

### 鍵の場所

`gpg --list-keys`:鍵の一覧を確認できます．
`gpg --list-secret-keys`:秘密鍵の一覧を確認できます．
` gpg --keyserver Servername --send-keys Keyname`:鍵を公開鍵サーバへ送る．
`gpg --keyserver Servername --search-keys KeyID`:鍵を公開鍵サーバで検索する
`gpg --keyserver Servername --recv-keys KeyID`:鍵を公開鍵サーバから入手する

```
$ gpg --list-keys
gpg: 信用データベースの検査
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: 深さ: 0  有効性:   2  署名:   0  信用: 0-, 0q, 0n, 0m, 0f, 2u
gpg: 次回の信用データベース検査は、2019-10-30です
/home/gyokoyama/.gnupg/pubring.kbx
----------------------------------
pub   rsa1024 2019-09-30 [SC] [有効期限: 2019-10-30]
      610DC5714D9ECE6B6A62984451BD1BB482F9F00B
uid           [  究極  ] gyokoyama (create sample gpg-key) <hogehoge@gmail.com>
sub   rsa1024 2019-09-30 [E] [有効期限: 2019-10-30]

```
```
$gpg --list-secret-key
/home/gyokoyama/.gnupg/pubring.kbx
----------------------------------
sec   rsa1024 2019-09-30 [SC] [有効期限: 2019-10-30]
      610DC5714D9ECE6B6A62984451BD1BB482F9F00B
uid           [  究極  ] gyokoyama (create sample gpg-key) <hogehoge@gmail.com>
ssb   rsa1024 2019-09-30 [E] [有効期限: 2019-10-30]

```



## 参考文献
https://medium.com/ethical-hacking-ホワイトハッカー/gpg-を理解せよ-ed464ec89232
https://ja.wikipedia.org/wiki/GNU_Privacy_Guard
https://gist.github.com/hatsusato/1d5f0267bc9d02bb24c60bd7acc5a59a
http://web.wakayama-u.ac.jp/~takehiko/pgp.html
https://forums.ubuntulinux.jp/viewtopic.php?id=16163
http://www.xucker.jpn.org/pc/gpg.html
https://wiki.archlinux.jp/index.php/GnuPG#.E5.85.AC.E9.96.8B.E9.8D.B5.E3.81.AE.E3.82.A4.E3.83.B3.E3.83.9D.E3.83.BC.E3.83.88