ハードウェアの気になるあれこれ

技術的に興味のあることを調べて書いてくブログ。主にハードウェアがネタ。

GithubのGPG keysの設定を試した話

スポンサーリンク

これまでのブログの流れとはまっっっったく関係ないけど、唐突にgithubのGPG keysの設定を行ってみたのでそれの手順をメモ。

GithubのGPG keysの設定

これを設定するとgithubのコミットに署名を行うことが出来て、ログのとこに以下のような"Verified"というのが出ようになる。

f:id:diningyo-kpuku-jougeki:20190916141348p:plain
Githubのコミットログ

今回この作業を行うにあたって、以下の2つの記事が大変参考になりました。この場を借りてお礼申し上げます。 ありがとうございましたm(_ _)m

ということもあり、本記事で紹介するのは上記の2つの記事を追っていったら出来たよ!という報告レベルの話です。 それでも読んでやるぜって方のみ、この先にお進みください。

gpg2のインストール

今回作業したマシンに入っているOSはUbuntu 16.04 LTSとなっています。上記のQiitaの記事によればgpgには大きく3つのバージョンがあるそうなのですが、Ubuntu 16.04 LTSに入っているgpgコマンドは古い"1.4.x"となっていました。

$ gpg --version
gpg (GnuPG) 1.4.20
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: ~/.gnupg
サポートしているアルゴリズム:
公開鍵: RSA, RSA-E, RSA-S, ELG-E, DSA
暗号方式: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256,
              TWOFISH, CAMELLIA128, CAMELLIA192, CAMELLIA256
ハッシュ: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
圧縮: 無圧縮, ZIP, ZLIB, BZIP2
$ gpg --gen-key --expert
gpg (GnuPG) 1.4.20; Copyright (C) 2015 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 (機能をあなた自身で設定)
選択は?

こちらだと楕円暗号が使えないようなので、新しい"2.x"系列を使うことにしました。

$ apt search gpg
ソート中... 完了
全文検索... 完了
~略~
gpgv/xenial-updates,xenial-security,now 1.4.20-1ubuntu3.3 amd64 [インストール済み]
  GNU privacy guard - 署名確認ツール

gpgv2/xenial-updates,xenial-security,now 2.1.11-6ubuntu2.1 amd64 [インストール済み] <-- version2っぽいのでこれを入れる
  GNU privacy guard - signature verification tool (new v2.x)
$ sudo apt install gpgv2
$ gpg2 --version
gpg (GnuPG) 2.1.11
libgcrypt 1.6.5
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: ~/.gnupg
サポートしているアルゴリズム:
公開鍵: RSA, ELG, DSA, ECDH, ECDSA, EDDSA <-- ECDH/ECDSA/EDDSAが増えている
暗号方式: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256,
      TWOFISH, CAMELLIA128, CAMELLIA192, CAMELLIA256
ハッシュ: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
圧縮: 無圧縮, ZIP, ZLIB, BZIP2

Master Keyの作成

今回はgpg のはなしに従い、Master KeyとSub Keyを分離して管理する方針で作ってみました。 Master KeyはSubkeyの管理にのみ使うようにして、通常の認証等の作業においては生成したSubkeyを使うと良いとのこと。Master Keyが必要になるのは

  • Subkeyを何らかの理由により無効化したい
  • Subkeyの期限が切れた(切れそうな)ので新しいSubkeyを作りたい(もしくは期限を延長したい)

と言ったケースになるので、Master Key自体の有効期限は永続で問題ないとのこと。

以下実行時のログ。

$ gpg2 --full-gen-key --expert
gpg (GnuPG) 2.1.11; Copyright (C) 2016 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: keybox'/home/diningyo/.gnupg/pubring.kbx'が作成されました
ご希望の鍵の種類を選択してください:
   (1) RSA と RSA (デフォルト)
   (2) DSA と Elgamal
   (3) DSA (署名のみ)
   (4) RSA (署名のみ)
   (7) DSA (機能をあなた自身で設定)
   (8) RSA (機能をあなた自身で設定)
   (9) ECC と ECC
  (10) ECC (署名のみ)
  (11) ECC (機能をあなた自身で設定)
あなたの選択は? 11

鍵ECDSAに認められた操作: Sign Certify Authenticate
現在の認められた操作: Sign Certify

   (S) 署名機能を反転する
   (A) 認証機能を反転する
   (Q) 完了

あなたの選択は? s

鍵ECDSAに認められた操作: Sign Certify Authenticate
現在の認められた操作: Certify

   (S) 署名機能を反転する
   (A) 認証機能を反転する
   (Q) 完了

あなたの選択は? q
ご希望の楕円曲線を選択してください:
   (1) Curve 25519
   (2) NIST P-256
   (3) NIST P-384
   (4) NIST P-521
   (5) Brainpool P-256
   (6) Brainpool P-384
   (7) Brainpool P-512
あなたの選択は? 1
gpg: WARNING: Curve25519 is not yet part of the OpenPGP standard.
Use this curve anyway? (y/N) N
   (1) Curve 25519
   (2) NIST P-256
   (3) NIST P-384
   (4) NIST P-521
   (5) Brainpool P-256
   (6) Brainpool P-384
   (7) Brainpool P-512
あなたの選択は? 4
鍵の有効期限を指定してください。
         0 = 鍵は無期限
      <n>  = 鍵は n 日間で期限切れ
      <n>w = 鍵は n 週間で期限切れ
      <n>m = 鍵は n か月間で期限切れ
      <n>y = 鍵は n 年間で期限切れ
鍵の有効期間は? (0) 0
(null)は無期限です
これで正しいですか? (y/N) y

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

本名: diningyo
電子メール・アドレス: xxxx@yyyy.zzzz
コメント: master
次のユーザIDを選択しました:
    "diningyo (master) <xxxx@yyyy.zzzz>"

名前(N)、コメント(C)、電子メール(E)の変更、またはOK(O)か終了(Q)? O

<ここの間で以下に載せた画像のようなパスワード設定画面が出現>

たくさんのランダム・バイトの生成が必要です。キーボードを打つ、マウスを動か
す、ディスクにアクセスするなどの他の操作を素数生成の間に行うことで、乱数生
成器に十分なエントロピーを供給する機会を与えることができます。
gpg: /home/diningyo/.gnupg/trustdb.gpg: 信用データベースができました
gpg: 鍵yyyyyyyyを究極的に信用するよう記録しました
gpg: ディレクトリ'/home/diningyo/.gnupg/openpgp-revocs.d'が作成されました
gpg: revocation certificate stored as '/home/diningyo/.gnupg/openpgp-revocs.d/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.rev'
公開鍵と秘密鍵を作成し、署名しました。

gpg: 信用データベースの検査
gpg: marginals needed: 3  completes needed: 1  trust model: PGP
gpg: 深さ: 0  有効性:   1  署名:   0  信用: 0-, 0q, 0n, 0m, 0f, 1u
pub   nistp521/yyyyyyyy 2019-09-16 []
      フィンガープリント = yyyyyyyy
uid         [  究極  ] diningyo (master) <xxxx@yyyy.zzzz>

途中で以下のパスワード画面が出たので、お好みのパスワードを設定してください。

f:id:diningyo-kpuku-jougeki:20190916141813p:plain
Master Keyのパスワード設定

参考記事と異なるのは以下の2点位

  • gpgだと"1.4.x"のgpgコマンドが呼ばれるので、代わりにgpg2を使う
  • Curve25519は「まだOpenPGPの標準じゃないよー」って言われたのでNISTのP-521に変更。
    • 後から気づいたけどMaster Keyは別にそれでも良かった

Subkeyの設定

Master Keyを使って普段使い用のSubkeyを作成します。 先ほど生成したMaster Keyの"/home/diningyo/.gnupg/openpgp-revocs.d/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.rev"の"xxxxx・・・"を--edit-keyに指定してgpgのシェル画面を起動をします。

$ gpg2 --expert --edit-key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx <- 上記の.gnupg/openpgp-revocs.d/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.revのrev以前を指定
gpg (GnuPG) 2.1.11; Copyright (C) 2016 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  nistp521/yyyyyyyy
     作成: 2019-09-16  有効期限: 無期限       利用法: C
     信用: 究極        有効性: 究極
[  究極  ] (1). diningyo (master) <xxxx@yyyy.zzzz>

gpg>gpg> addkey
ご希望の鍵の種類を選択してください:
   (3) DSA (署名のみ)
   (4) RSA (署名のみ)
   (5) Elgamal (暗号化のみ)
   (6) RSA (暗号化のみ)
   (7) DSA (機能をあなた自身で設定)
   (8) RSA (機能をあなた自身で設定)
  (10) ECC (署名のみ)
  (11) ECC (機能をあなた自身で設定)
  (12) ECC (暗号化のみ)
  (13) 既存の鍵
あなたの選択は? 11

鍵ECDSAに認められた操作: Sign Authenticate
現在の認められた操作: Sign

   (S) 署名機能を反転する
   (A) 認証機能を反転する
   (Q) 完了

あなたの選択は? a

鍵ECDSAに認められた操作: Sign Authenticate
現在の認められた操作: Sign Authenticate

   (S) 署名機能を反転する
   (A) 認証機能を反転する
   (Q) 完了

あなたの選択は? q
ご希望の楕円曲線を選択してください:
   (1) Curve 25519
   (2) NIST P-256
   (3) NIST P-384
   (4) NIST P-521
   (5) Brainpool P-256
   (6) Brainpool P-384
   (7) Brainpool P-512
あなたの選択は? 4
鍵の有効期限を指定してください。
         0 = 鍵は無期限
      <n>  = 鍵は n 日間で期限切れ
      <n>w = 鍵は n 週間で期限切れ
      <n>m = 鍵は n か月間で期限切れ
      <n>y = 鍵は n 年間で期限切れ
鍵の有効期間は? (0) 2y
鍵は2021年09月15日 13時23分03秒 JSTで期限切れとなります
これで正しいですか? (y/N) y
本当に作成しますか? (y/N) y
たくさんのランダム・バイトの生成が必要です。キーボードを打つ、マウスを動か
す、ディスクにアクセスするなどの他の操作を素数生成の間に行うことで、乱数生
成器に十分なエントロピーを供給する機会を与えることができます。

sec  nistp521/yyyyyyyy
     作成: 2019-09-16  有効期限: 無期限       利用法: C
     信用: 究極        有効性: 究極
ssb  nistp521/zzzzzzzz <-- Sign/Authenticateに使えるSubkeyが生成された
     作成: 2019-09-16  有効期限: 2021-09-15  利用法: SA
[  究極  ] (1). diningyo (master) <xxxx@yyyy.zzzz>

# 作り終わったらsaveして終了する
gpg> save

上記の鍵生成時(本当に作成しますか?)の後に先ほどと同様のパスワード設定の画面と、秘密鍵のロック解除のためのパスワード入力があるので、最初のパスワード設定は任意のパスワードを、ロック解除についてはMaster Key生成時のものを入力すればOK。

f:id:diningyo-kpuku-jougeki:20190916141728p:plain
Subkeyのパスワード設定

f:id:diningyo-kpuku-jougeki:20190916141749p:plain
Master Keyのロック解除

Master Keyの削除

安全のためにSubkey生成後はMaster Keyを.gnupgから削除してオフラインに保存するのがオススメとのことなので、それに倣ってMaster Keyの削除を行います。

まずはMaster Keyを保全するために"~/.gnupg"をディレクトリごとコピーしておきます。このコピーしたディレクトリはオフラインのディスクに入れて大事にしておきましょう。

次に--with-Keygripを指定してMaseter Keyのkeygripを確認。

$ gpg2 --with-keygrip --list-key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx <-- ここは--edit-keyの時と同じ
pub   nistp521/yyyyyyyy 2019-09-16 [C]
      Keygrip = MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM <-- これ
uid         [  究極  ] diningyo (master) <xxxx@yyyy.zzzz>
sub   nistp521/zzzzzzzz 2019-09-16 [SA] [有効期限: 2021-09-15]
      Keygrip = SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

上記で調べてkeygirpが含まれる"*.key"ファイルが"~/.gnupg/private-keys-v1.d/"の下にあるはずなのでこのファイルを削除。 Master Keyが正しく削除されたことを確認するためには以下のように、削除前/削除後でgpg2 --list-secret-keysを発行してsecの部分に#がついていないことを確認すればいいそうです。

  • ファイルの削除前
$ gpg2 --list-secret-keys
/home/diningyo/.gnupg/pubring.kbx
---------------------------------
sec   nistp521/yyyyyyyy 2019-09-16 [C]
uid         [  究極  ] diningyo (master) <xxxx@yyyy.zzzz>
ssb   nistp521/zzzzzzzz 2019-09-16 [SA] [有効期限: 2021-09-15]
  • ファイルの削除後
$ gpg2 --list-secret-keys
/home/diningyo/.gnupg/pubring.kbx
---------------------------------
sec#  nistp521/yyyyyyyy 2019-09-16 [C] <- sec#になってる
uid         [  究極  ] diningyo (master) <xxxx@yyyy.zzzz>
ssb   nistp521/zzzzzzzz 2019-09-16 [SA] [有効期限: 2021-09-15]

Subkeyのエクスポートしてgithubに登録

次は生成したSubkeyの公開鍵を取得します。gpg2に以下の2つのオプションを与えて実行すると公開鍵をasciiコードで取得出来るのでこれをgithubのGPG keyに設定します。

  • --armor : 出力をasciiコードの文字列で出力
  • --export <鍵のID> : --list-secret-keysで表示されるSub keyの部分の文字列(上記だと"zzzzzzzz")
$ gpg2 --armor --export zzzzzzzz
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2

"公開鍵の文字列"
=kOI0
-----END PGP PUBLIC KEY BLOCK-----

githubの設定ページから"SSH and GPG keys"を開き"New GPG key"を設定して表示される画面(下記)に上記の公開鍵を"BEGIN PGP PUBLIC KEY BLOCK"~"END PGP PUBLIC KEY BLOCK"を丸々貼り付けます。

f:id:diningyo-kpuku-jougeki:20190916141426p:plain
GPG keyの設定

それが終わると以下のようにGPG Keysに設定した公開鍵が登録された状態になります。

f:id:diningyo-kpuku-jougeki:20190916141449p:plain
GPG key登録後

コミットとプッシュのテスト

githubに登録している適当なリポジトリディレクトリに入って以下を実行。 鍵IDを登録して-Sオプション付きでコミットすると署名付きのコミットになる。

-S[<keyid>], --gpg-sign[=<keyid>]
    GPG-sign commits. The keyid argument is optional and defaults to the committer identity;
    if specified, it must be stuck to the option without a space.
git config --global gpg.program gpg2 # ここgpg2にしないと失敗する
git config --global user.signingkey zzzzzzzz # 使用する鍵のIDを指定
touch test
git add test
git commit -m "test" -S # -S で署名付きのコミットになる
git push origin master # プッシュ

上記にもあるとおりgpg2をプログラムとして指定しないと以下のようなエラーが発生してコミットに失敗するのでそこだけ注意。

$ git commit -m "test commit with gpg" -S
error: gpg はデータを署名するのに失敗しました
fatal: failed to write commit object

設定に問題なければgit pushが正常に完了し、冒頭のgithubのコミットログにあるようにVerifiedが表示されるようになる。

ということでGPG keyの設定を試してみた話でした。