BETA

GnuPGでファイルを署名する

投稿日:2019-05-18
最終更新:2019-05-18

Emacsのパッケージがインストールされるのを眺めるで.sigという拡張子のファイルをダウンロードしていました。これはGnuPGの署名ファイルです。今回はこの署名ファイルの検証をしてみます。また自分で署名ファイルを作成もしてみます。

なお実行環境のOSはmacOS Mojaveです。

おしながき

  1. 準備
    1. GnuPGとは
    2. GnuPGのインストール
    3. gpg-agentのインストール
    4. pinentry-macのインストール
    5. gpg-agentがpinentry-macを使うための設定
  2. 鍵を作成する
  3. 署名を検証する
  4. 署名を作成する
  5. 公開鍵を公開する
    1. 公開鍵をエクスポートする
    2. PGP公開鍵サーバーに公開鍵をアップロードする
  6. まとめ
  7. 参考

準備

GnuPGとは

GNU Privacy Guard (GnuPG, GPG) とは、Pretty Good Privacy (PGP) の別実装として、GPL に基づいた暗号化ソフトである。 OpenPGP 規格 (RFC 4880) に完全準拠しているが、古い PGP との互換性は完全ではない。
(Wikipediaより: GNU Privacy Guard - https://ja.wikipedia.org/wiki/GNU_Privacy_Guard)

要は暗号化や署名といった機能を提供します。誰かにデータを渡したり渡されたりする際、データの中身を見られないようにしたり、そのデータが本当に本人から渡されたことを保証するためのツールです。様々な場面で使われていますが、例えばパッケージ管理ツールはPGPの機構を利用してダウンロードしたファイルを検証しています。

GnuPGのインストール

今回はHomebrewを使ってインストールします。

brew install gnupg  

インストールされたGnuPGのバージョンを確認します。

gpg --version  

出力

gpg (GnuPG) 2.2.13  
libgcrypt 1.8.4  
Copyright (C) 2019 Free Software Foundation, Inc.  
License GPLv3+: GNU GPL version 3 or later <https://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.  

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

gpg-agentのインストール

gpg-agentは秘密鍵を任意のプロトコルから独立して管理します。

https://www.gnupg.org/documentation/manuals/gnupg/Invoking-GPG_002dAGENT.html

brew install gpg-agent  

gpgはpgp-agentをバックエンドとして利用されます。gpg-agentのプロセスはgpgなどの起動時に自動的に起動されます。

pinentry-macのインストール

pinentryはGnuPGのパスフレーズやPIN番号を入力する手段を提供するプログラムです。macOSではmacOS用のpinentry-macをインストールするとパスフレーズ入力時などにGUIのダイアログが開くようになります。

Homebrewを使ってインストールします。

brew install pinentry-mac  

gpg-agentがpinentry-macを使うための設定

gpg-agentにpinentry-macを利用させるには~/.gnupg/gpg-agent.confに次の設定をします。

use-standard-socket  
pinentry-program /usr/local/bin/pinentry-mac  

設定が完了したら設定を読み込ませるためにgpg-agentを一度終了します。

gpgconf --kill all  

鍵を作成する

自分の鍵を作成してみます。作成には --gen-key オプションを指定します。通常はインタラクティブな画面上のやりとりが必要ですが --batch を指定することで設定ファイルからも鍵を生成できます。

master.confの中身

# プライマリキー  
Key-Type: RSA  
Key-Length: 4096  

# サブキー  
Subkey-Type: RSA  
Subkey-Length: 4096  

# プライマリキー及びサブキーの有効期間を1ヶ月に設定  
Expire-Date: 1m  

# 名前とメールアドレスを設定  
Name-Real: sximada  
Name-Email: [email protected]  

# パスフレーズを設定 (大文字小文字・数字・記号を混ぜた安全なパスフレーズを指定してください)  
Passphrase: xxxxxxxxxxx  

# 上記の内容で鍵ペアを作成  
%commit  
%echo Successfully done  

設定ファイルの詳しい書き方はhttps://www.gnupg.org/documentation/manuals/gnupg/Unattended-GPG-key-generation.htmlに書かれています。

では鍵を生成します。

gpg --gen-key --batch master.conf  

出力

gpg: 鍵3DEB51DB0CA60F0Aを究極的に信用するよう記録しました  
gpg: ディレクトリ'/Users/xxx/.gnupg/openpgp-revocs.d'が作成されました  
gpg: 失効証明書を '/Users/xxx/.gnupg/openpgp-revocs.d/27621C5B18388278B335B3903DEB51DB0CA60F0A.rev' に保管しました。  
gpg: Successfully done  

生成に成功したようです。master.confの設定にしたがって鍵が作成されました。
/Users/xxx/.gnupg/openpgp-revocs.d に出力されたのは失効証明書です。秘密鍵が漏れたなどの理由で鍵の失効をしなくてはいけなくなった時に使います。

署名を検証する

前回確認したarchive-contentsの署名を確認します。まずはarchive-contentsファイルとその署名ファイルをelpaからダウンロードします。

curl https://elpa.gnu.org//packages/archive-contents -o archive-contents  
curl https://elpa.gnu.org//packages/archive-contents.sig -o archive-contents.sig  
ファイル名 説明
archive-contents elpaのindex情報
archive-contents.sig archive-contentsの署名

ではこの署名を検証します。 --verify と署名ファイルを指定します。署名対象のファイルも指定できますが省略した場合は.sig拡張子が取られた状態のファイルを対象にします。

gpg --verify archive-contents.sig  

出力

gpg: 署名されたデータが'archive-contents'にあると想定します  
gpg: 金  5/17 06:10:03 2019 JSTに施された署名  
gpg:                DSA鍵CA442C00F91774F17F59D9B0474F05837FBDEF9Bを使用  
gpg: 署名を検査できません: No public key  

署名の検査に失敗しました。 No public key と出力されています。署名の検証には公開鍵を使いますがそれがないようです。署名に使用された鍵は CA442C00F91774F17F59D9B0474F05837FBDEF9B です。この鍵を探してみます。鍵の検索には --search-key と探す鍵を指定します。

gpg --search-key CA442C00F91774F17F59D9B0474F05837FBDEF9B  

鍵が見つかるとその情報が表示されます。鍵の番号を入力しエンターを押すと鍵がインポートされます。

gpg: data source: https://51.38.91.189:443  
(1)    GNU ELPA Signing Agent <[email protected]>  
    GNU ELPA Signing Agent (2014) <[email protected]>  
      2048 bit DSA key 474F05837FBDEF9B, 作成: 2014-09-24, 有効期限: 2019-09-23  
Keys 1-1 of 1 for "CA442C00F91774F17F59D9B0474F05837FBDEF9B".  番号(s)、N)次、またはQ)中止を入力してください >1  
gpg: 鍵474F05837FBDEF9B: 公開鍵"GNU ELPA Signing Agent (2014) <[email protected]>"をインポートしました  
gpg:           処理数の合計: 1  
gpg:             インポート: 1  

インポートされた鍵を確認します。鍵の一覧を確認するには -k を指定します。

gpg -k  

出力

/Users/xxx/.gnupg/pubring.kbx  
---------------------------------  
pub   rsa4096 2019-05-17 [SCEA] [有効期限: 2019-06-16]  
      2762 1C5B 1838 8278 B335  B390 3DEB 51DB 0CA6 0F0A  
uid           [  究極  ] sximada <[email protected]>  
sub   rsa4096 2019-05-17 [SEA] [有効期限: 2019-06-16]  

pub   dsa2048 2014-09-24 [SC] [有効期限: 2019-09-23]  
      CA44 2C00 F917 74F1 7F59  D9B0 474F 0583 7FBD EF9B  
uid           [  不明  ] GNU ELPA Signing Agent (2014) <[email protected]>  
uid           [  不明  ] GNU ELPA Signing Agent <[email protected]>  

再度署名を検証します。

gpg --verify archive-contents.sig  

出力

gpg: 署名されたデータが'archive-contents'にあると想定します  
gpg: 金  5/17 06:10:03 2019 JSTに施された署名  
gpg:                DSA鍵CA442C00F91774F17F59D9B0474F05837FBDEF9Bを使用  
gpg: "GNU ELPA Signing Agent (2014) <[email protected]>"からの正しい署名 [不明の]  
gpg:                 別名"GNU ELPA Signing Agent <[email protected]>" [不明の]  
gpg: *警告*: この鍵は信用できる署名で証明されていません!  
gpg:       この署名が所有者のものかどうかの検証手段がありません。  
 主鍵フィンガープリント: CA44 2C00 F917 74F1 7F59  D9B0 474F 0583 7FBD EF9B  

先ほどインポートした公開鍵が信用できるものとして登録されていないので警告が出ます。鍵の信用を設定するためには --edit-key オプションを使います。

gpg --edit-key CA442C00F91774F17F59D9B0474F05837FBDEF9B  

コマンドを実行するとインタラクティブに操作を求めてきます。trustコマンドを実行し公開鍵の信用を設定します。

gpg (GnuPG) 2.2.13; Copyright (C) 2019 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.  


pub  dsa2048/474F05837FBDEF9B  
     作成: 2014-09-24  有効期限: 2019-09-23  利用法: SC    
     信用: 不明の     有効性: 不明の  
[  不明  ] (1). GNU ELPA Signing Agent (2014) <[email protected]>  
[  不明  ] (2)  GNU ELPA Signing Agent <[email protected]>  

gpg> trust  
pub  dsa2048/474F05837FBDEF9B  
     作成: 2014-09-24  有効期限: 2019-09-23  利用法: SC    
     信用: 不明の     有効性: 不明の  
[  不明  ] (1). GNU ELPA Signing Agent (2014) <[email protected]>  
[  不明  ] (2)  GNU ELPA Signing Agent <[email protected]>  

他のユーザの鍵を正しく検証するために、このユーザの信用度を決めてください  
(パスポートを見せてもらったり、他から得たフィンガープリントを検査したり、などなど)  

  1 = 知らない、または何とも言えない  
  2 = 信用し ない  
  3 = まぁまぁ信用する  
  4 = 充分に信用する  
  5 = 究極的に信用する  
  m = メーン・メニューに戻る  

あなたの決定は? 5  
本当にこの鍵を究極的に信用しますか? (y/N) y  

pub  dsa2048/474F05837FBDEF9B  
     作成: 2014-09-24  有効期限: 2019-09-23  利用法: SC    
     信用: 究極        有効性: 不明の  
[  不明  ] (1). GNU ELPA Signing Agent (2014) <[email protected]>  
[  不明  ] (2)  GNU ELPA Signing Agent <[email protected]>  
プログラムを再起動するまで、表示された鍵の有効性は正しくないかもしれない、  
ということを念頭においてください。  

gpg> quit  

再度署名の検証を行います。

gpg --verify archive-contents.sig  

出力

gpg: 署名されたデータが'archive-contents'にあると想定します  
gpg: 金  5/17 06:10:03 2019 JSTに施された署名  
gpg:                DSA鍵CA442C00F91774F17F59D9B0474F05837FBDEF9Bを使用  
gpg: 信用データベースの検査  
gpg: marginals needed: 3  completes needed: 1  trust model: pgp  
gpg: 深さ: 0  有効性:   2  署名:   0  信用: 0-, 0q, 0n, 0m, 0f, 2u  
gpg: 次回の信用データベース検査は、2019-06-16です  
gpg: "GNU ELPA Signing Agent (2014) <[email protected]>"からの正しい署名 [究極]  
gpg:                 別名"GNU ELPA Signing Agent <[email protected]>" [究極]  

今回は署名の検証が成功しました。

署名を作成する

今度はファイルに対して署名を作成してみます。署名を作るファイルはこのような内容のテキストファイルにします。

!"#$%&'()*+,-./0123456789:;<=>[email protected][\]^_`abcdefghijklmnopqrstuvwxyz{|}~

gpg --detach-sign test.txt  

実行するとパスフレーズを入力するためのダイアログが表示されます。

正しいパスフレーズを入力するとtest.txt.sigが作成されます。

作成した署名を確認するには以前と同様 --verity を使って.sigファイルを指定します。

gpg --verify test.txt.sig  

出力はこのように変わります。

gpg: 署名されたデータが'test.txt'にあると想定します  
gpg: 金  5/17 18:47:59 2019 JSTに施された署名  
gpg:                RSA鍵656F942AE22C3745399E2AF875C619F5A386C062を使用  
gpg: "sximada <[email protected]>"からの正しい署名 [究極]  

適切に署名ができていることがわかります。

公開鍵を公開する

誰かにこの署名を検証してもらうためには自分の公開鍵を渡します。公開鍵をエクスポートしてWeb上のどこかに置いておくか、またはPGP公開鍵サーバーに公開鍵をアップロードするという方法もあります。

公開鍵をエクスポートする

公開鍵をWeb上に配置するにせよ誰かに渡すにせよ、GnuPGが内部的に管理している状態では渡すこともできず不便です。 --export を使って公開鍵を出力してそれを渡します。

gpg --export --armor  

このテキストが公開鍵ですので必要に応じてこれを渡せばば良いです。逆にインポートは --import FILENAME で取り込めます。

PGP公開鍵サーバーに公開鍵をアップロードする

より多くの人に使ってもらいたい場合はPGP公開鍵サーバーに公開鍵をアップロードするほうが好ましいかもしれません。PGP公開鍵サーバーを使うことで何が嬉しいかというと、鍵の検索やインポートをgpgコマンドのみでできるというところです。

鍵の一覧を確認します。

gpg -k  

--keyserver で送信するサーバーを指定し --send-keys で送信する鍵を指定します。コマンドはこのようになります。今回は継続使うものではないので送信はしませんでした。

gpg --keyserver pgp.mit.edu --send-keys 27621C5B18388278B335B3903DEB51DB0CA60F0A  

公開鍵は送信すると削除はできません(失効は失効証明書を使うことで可能です)。

まとめ

以下のことを実施しました。

  • GnuPGとは何かを説明し、使用できる環境を作成した
  • 自分の鍵を作成しどこのディレクトリに配置されたのかを確認した
  • 署名を検証した実際のデータ(elpaのインデックス情報)を使って学んだ
  • 自分の鍵を使用してファイルを署名する手順を学んだ
  • 自分の公開鍵を公開する方法を学んだ

GnuPGを扱う上でだいたい一通りのことを今回実施しました。使い方はとっつきにくいですが慣れればそれほどでもないので色々と触ってみると良いかもしせません。

参考

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

そして粛々と生きる

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!