Skip to content

Instantly share code, notes, and snippets.

@hatsusato
Last active November 25, 2023 05:46
  • Star 62 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save hatsusato/1d5f0267bc9d02bb24c60bd7acc5a59a to your computer and use it in GitHub Desktop.
gpg のはなし

gpg のはなし

この記事は KMC Advent Calendar 2017 の 10 日目の記事です。 昨日の記事は tron 君 (id:tron_kmc) の今年の活動を振り返る - tron-Factory 業務日誌でした。 はたち:tada:めでたい:congratulations:

はじめに

KMC 6 回生の hatsusato です。 修士 2 回生ともなると研究にかまけて KMC 活動がおろそかになっているので、この場を借りて申し訳程度に KMC 活動をしようと思います。

この記事は 10 日目の予定でしたが、 10 日には KMC の追い出しコンパがあり、僕も飲み会に出席しなければならなかったので、遅刻も致し方なしなのです(言い訳)。

この記事における記述は、自分の環境である Ubuntu 17.10 におけるものをもとにしています。 それ以外の環境でも、 Ubuntu の他のバージョンや Debian あたりであれば問題なくそのまま動くような気がしますがあしからず。

パスワード管理

そもそも、みなさんはパスワード管理をどうやって行っていますか? 僕はこれまで LastPass さんに頼っていたのですが、インターネット上の日常生活における、この本質的に重要な課題を一私企業に依存しすぎるのはよくないなと感じていました。

そこで見つけたのが Pass という ググラビリティの低そうな フリーソフトウェアです。 僕はこれがいたく気に入りまして、パスワード管理環境をこちらに移行しようと考えております1

Pass

Pass はその冒頭

Password management should be simple and follow Unix philosophy.

にもあるように、 Unix 哲学に則ったシンプルな設計のパスワード管理ソフトです。 やっていることは、単に git管理 されたディレクトリ以下に gpg暗号化 されたパスワードファイルを配置しているだけです。 ね、かんたんでしょう?

この記事では Pass の詳細に立ち入るつもりはないので、興味があれば公式サイトman pass をどうぞ。

gpg 暗号化

先述したように、 Pass は機密情報の暗号化に gpg を用いています。

gpg とは、 GNU Privacy Guard の略で、暗号化だけでなく署名や認証といったオンライン上の機密や信用を管理するツールです。 暗号化するだけなら openssl など他の選択肢もありますが、 gpg は他にはない専用の環境をもつという特徴があります。 この環境の意義や役割を学ぶのに時間を要したので、そのあたりの知見を書き記そうというのがこの記事です。 ここまでまえがき。

gpg

まず gpg をインストールしましょう。

$ sudo apt install gnupg

gpg を利用するなら、鍵を作らなければなりません。

$ gpg --gen-key

を実行すると、主鍵 (Master key) の作成をインタラクティブに開始できます。 その過程であなたは名前やメールアドレスなどを要求されるでしょう。 それらはこの Master key に紐付けられ、 Master key はインターネット上におけるあなたのアイデンティティそのものになります。 この鍵によって、インターネットを介していても、第三者があなたと他の人とを区別できるようになります。

一方、そのために、 Master key が漏洩すれば何者かがあなたを騙ることができるようになりますし、 Master key を失うことはすなわちインターネット上のアイデンティティの喪失を意味します。 そうすると、あなたはインターネット上における信用形成をゼロからやり直さなくてはならなくなります。 gpg --gen-key が生成する Master key はこのような重要な役割を果たす鍵ですので、確実に守らなければなりません。

Subkey

そんな大事な鍵は普段使いしたくはありませんね。 そのため、 gpg では 副鍵 (Subkey) という Master key とは別の鍵を利用することができます。

$ gpg --edit-key <Master keyのIDなど>
<中略>
gpg> addkey

とすると、 Subkey の作成をインタラクティブに開始できます。

  • <Master keyのIDなど> の部分には、 Master key の ID そのもの以外にも、 fingerprint やメールアドレスなども指定できます。 詳しくは man gpgHOW TO SPECIFY A USER ID の項を参照してください。

この Subkey は対応する Master key によって署名されており、 Master key と同等の認証情報をもちます。 一方で、 Subkey が漏洩しても Master key 自体の情報は漏洩しません。 漏洩した Subkey のみを無効化し、新しい Subkey に置き換えることを、 Master key の信用を傷つけることなく行うことができます。

そこで、

  1. Master key を作成したら、

  2. 早速 Subkey を作成し、

  3. 普段利用するマシンには Subkey だけを残し、

  4. Master key はどこか安全な場所にしまっておく、

という運用をします。 Master key を使う場面は、 Subkey を無効化したり、有効期限を変更したりするなど、設定変更のときだけです。 そのため、 Master key を普段オフラインの状況においておいて、 Master key が漏洩する心配を減らすことができます。

鍵を作る例

Master key と Subkey の役割を理解したところで、実際にやってみましょう。

$ gpg --expert --full-gen-key
gpg (GnuPG) 2.1.15; 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.

ご希望の鍵の種類を選択してください:
   (1) RSA と RSA (デフォルト)
   (2) DSA と Elgamal
   (3) DSA (署名のみ)
   (4) RSA (署名のみ)
   (7) DSA (機能をあなた自身で設定)
   (8) RSA (機能をあなた自身で設定)
   (9) ECC と ECC
  (10) ECC (署名のみ)
  (11) ECC (機能をあなた自身で設定)
あなたの選択は? 11

今回は、せっかくなので、デフォルトのアルゴリズム (RSA) ではなく楕円曲線暗号 (ECC) の方を使ってみようと思います。

  • --gen-key ではなく --full-gen-key を指定して --expert も指定しないと ECC の選択肢が現れないことに注意してください。

鍵には署名や認証などの機能を個別に設定したり2、同時に暗号化 Subkey も生成したり3することができます。

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

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

あなたの選択は? s

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

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

あなたの選択は? q

機能をあなた自身で設定を選択すると Sign Certify Authenticate のどの機能を Master key に持たせるかを選択できます。 機能フラグを適宜反転させて、現在の認められた操作にほしい機能が並んでいることを確認したら完了を選択します。

  • 今回は Master key には最低限の機能 Certify だけをもたせ、それ以外の機能は Subkey を用いて実現することにします。
ご希望の楕円曲線を選択してください:
   (1) Curve 25519
   (3) NIST P-256
   (4) NIST P-384
   (5) NIST P-521
   (6) Brainpool P-256
   (7) Brainpool P-384
   (8) Brainpool P-512
   (9) secp256k1
あなたの選択は? 1

楕円曲線暗号で用いる楕円曲線の種類を選択します。

  • ここでは、 Curve 255194 を選択してみます。
鍵の有効期限を指定してください。
         0 = 鍵は無期限
      <n>  = 鍵は n 日間で期限切れ
      <n>w = 鍵は n 週間で期限切れ
      <n>m = 鍵は n か月間で期限切れ
      <n>y = 鍵は n 年間で期限切れ
鍵の有効期間は? (0) 0
(null)は無期限です
これで正しいですか? (y/N) y

鍵には有効期限を設定することができます。 有効期限が切れた鍵は、有効期限を延長しない限り使えなくなるので、いざ鍵を盗まれたときに、その鍵を悪用される期間を制限することができます。 しかし、有効期限の延長は Master key を用いて行うので、 Master key に対する有効期限はほとんど無意味です。 なので、ここは 0 でよいでしょう。

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

本名: <あなたの名前>
電子メール・アドレス: <あなたの@メールアドレス>
コメント: <任意のコメント(この鍵の役割とか?)>
次のユーザIDを選択しました:
    "あなたの名前 (コメント) <あなたの@メールアドレス>"

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

鍵にあなたの個人情報を関連付けます。

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

pub   ed25519 2017-12-10 [C]
      XXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYYYYYYY
uid                      あなたの名前 (コメント) <あなたの@メールアドレス>

あとは乱数生成器にエントロピーが溜まるのを待つだけです。 XXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYYYYYYY の部分がこの Master key の ID になります。

Subkey を作る

続いて、 Subkey を作っていきましょう。

$ gpg --expert --edit-key XXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYYYYYYY
gpg (GnuPG) 2.1.15; 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: 信用データベースの検査
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: 深さ: 0  有効性:   3  署名:   0  信用: 0-, 0q, 0n, 0m, 0f, 3u
sec  ed25519/YYYYYYYYYYYYYYYY
     作成: 2017-12-10  有効期限: 無期限       利用法: C   
     信用: 究極        有効性: 究極
[  究極  ] (1). あなたの名前 (コメント) <あなたの@メールアドレス>

gpg> addkey

Subkey を作るには --edit-key のあとに addkey コマンドを実行します。 今回も作成する Subkey に楕円曲線暗号を使うために --expert オプションをつけています。

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

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

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

あなたの選択は? s

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

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

あなたの選択は? a

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

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

あなたの選択は? q

(10) を指定すれば署名用の Subkey を、 (12) を指定すれば暗号化用の Subkey を作成できます。 (11) を指定すれば、適宜フラグを反転することで、署名用、認証用、署名認証両用の3種類の Subkey を選択できます。 上の例では認証用の Subkey を選択しています。

  • 署名用や認証用の Subkey は複数作って使い分けてもよいです。

  • gpg は暗号化用の Subkey が複数あっても 1 つ目の鍵しか用いないので、暗号化用の Subkey は 1 つ作れば十分です。

ご希望の楕円曲線を選択してください:
   (1) Curve 25519
   (3) NIST P-256
   (4) NIST P-384
   (5) NIST P-521
   (6) Brainpool P-256
   (7) Brainpool P-384
   (8) Brainpool P-512
   (9) secp256k1
あなたの選択は? 1

Master key と同じ曲線にしました。

鍵の有効期限を指定してください。
         0 = 鍵は無期限
      <n>  = 鍵は n 日間で期限切れ
      <n>w = 鍵は n 週間で期限切れ
      <n>m = 鍵は n か月間で期限切れ
      <n>y = 鍵は n 年間で期限切れ
鍵の有効期間は? (0) 1y
鍵は2018年12月10日 00時00分00秒 JSTで期限切れとなります

Master key とは異なり、 Subkey には有効期限を設定しておくのがよいでしょう。 期間があまり短いと、頻繁に期限の延長をする必要があり面倒くさいですが、より安心できます。 一方、期間が長過ぎると、有効期限を設定している意味が薄れてしまいます。

  • ここではとりあえず 1 年としてみましたが、お好みで調整してください。
これで正しいですか? (y/N) y
本当に作成しますか? (y/N) y
たくさんのランダム・バイトの生成が必要です。キーボードを打つ、マウスを動か
す、ディスクにアクセスするなどの他の操作を素数生成の間に行うことで、乱数生
成器に十分なエントロピーを供給する機会を与えることができます。

sec  ed25519/YYYYYYYYYYYYYYYY
     作成: 2017-12-10  有効期限: 無期限       利用法: C   
     信用: 究極        有効性: 究極
ssb  ed25519/ZZZZZZZZZZZZZZZZ
     作成: 2017-12-10  有効期限: 2018-12-10  利用法: A   
[  究極  ] (1). あなたの名前 (コメント) <あなたの@メールアドレス>

gpg> save

最後に save して変更を保存するのを忘れないように。

これで Subkey が 1 つできました。 必要なだけ addkey を繰り返して、 Subkey を揃えましょう。

Master key を取り除く

鍵の情報はデフォルトでは ~/.gnupg/ 以下に保存されています。 このままではこのディレクトリを読み取られると Master key の秘密鍵が漏洩してしまうので、 .gnupg から秘密鍵を取り除きましょう。

まず、 .gnupg ディレクトリのバックアップを取りましょう。 このバックアップはオフラインのストレージに保存するなどして、メインマシンとは分けて保管しましょう。

  • Master keyの秘密鍵さえバックアップすれば十分ですが、ディレクトリごとバックアップしておけば、環境変数 GNUPGHOME--homedir オプションによって、一時的にバックアップの .gnupg ディレクトリを用いて gpg コマンドを実行することができて便利です。

続いて、 Master key の秘密鍵を削除します。 まず、 Master key の keygrip を調べます。

$ gpg --with-keygrip --list-key XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
pub   ed25519 2017-12-10 [C]
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      Keygrip = YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
uid           [  究極  ] あなたの名前 (コメント) <あなたの@メールアドレス>
sub   ed25519 2017-12-10 [A] [有効期限: 2018-12-10]
      Keygrip = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
sub   ed25519 2017-12-10 [S] [有効期限: 2018-12-10]
      Keygrip = SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
sub   cv25519 2017-12-10 [E] [有効期限: 2018-12-10]
      Keygrip = EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE

keygrip は gpg --with-keygrip --list-key コマンドを実行することで調べることができます。 上の例における YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY の部分が Master key の keygrip になります。

$ rm ~/.gnupg/private-keys-v1.d/YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY.key
$ gpg --list-secret-keys
sec#  ed25519 2017-12-10 [C]
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
uid           [  究極  ] あなたの名前 (コメント) <あなたの@メールアドレス>
ssb   ed25519 2017-12-10 [A] [有効期限: 2018-12-10]
ssb   ed25519 2017-12-10 [S] [有効期限: 2018-12-10]
ssb   cv25519 2017-12-10 [E] [有効期限: 2018-12-10]

先程調べた keygrip を名前にもつファイルが .gnupg/private-keys-v1.d/ の下にあるので、そのファイルを削除します。 すると、 gpg --list-secret-keys コマンドの出力の冒頭が、 sec ではなく sec# となります。 これは、 ~/.gnupg/ 以下に秘密鍵が存在しないことを表しています。

お疲れ様です。 これで gpg 環境のセットアップは完了しました。

まとめ

  • Master key は大事な鍵なので、オフラインで保管するなどして大事に扱いましょう。

  • Master key の代わりに普段使いする Subkey を使いましょう。

  • マシンの上には Subkey だけ残して、 Master key はバックアップした後にマシンから削除しましょう。

この記事の内容は、 Debian Wiki を参考にしました。

KMC Advent Calendar 2017 の明日の記事は polaris 君のその日に考えること+10代の終わりについての記事の予定です。 polaris 君は多分 1 回生だと思うのですが、僕は今の 1 回生をほとんど把握していません。 一線を退いた感じがします。 今どきの 1 回生はどんなことを考えるのでしょうか。


1まだ移行完了してない。

2署名のみ機能をあなた自身で設定の部分

3XXX と YYYYYY の方が暗号化 Subkey に対応

4ググったところ、これが今一番イケてるっぽい要出典

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment