公開鍵暗号

26.8.3. 公開鍵暗号

公開鍵暗号系では,署名と検証,暗号化と復号を行うことができます. 通信相手の認証などの目的に,署名と検証は特に重要です.

公開鍵暗号システム #

公開鍵暗号では,個人ごとに,公開鍵と秘密鍵のペアを持ちます.秘密鍵を秘密に保ち,公開鍵を関係者に配布します.

つまり典型的な状況では,個人毎に,

  1. 自分の秘密鍵と公開鍵のペアと,
  2. 知り合い(複数)の公開鍵

を持ちます.

GoogleDriveの連携 #

公開鍵や秘密鍵をどこに保存するかを確認します.

Chromebook 端末の場合
GoogleDrive/MyDrive に保存しましょう.Linux 端末から MyDrive を使えるように設定しておきます — 14.1. ターミナル
BYOD の場合
各自のホームを使います

ターミナルの起動と作業フォルダの作成 #

Colab の場合, 画面下端のツールバーからターミナル terminal を起動します.

ターミナルを開かずにセルから実行することもできますが,コマンドが多少煩雑になります.

以降では,作業ディレクトリ gpg を作って,その中で作業します. Chromebook 端末と colab では,GoogleDrive/MyDrive の中に作りましょう. 個人の端末の場合は,ホームの下などで問題ありません.

Colab ではまず GoogleDrive を接続しておきましょう.

作業場所として MyDrive/gpg というフォルダを作ります. GUIで作っても良いですし,CUIで作ることもできます.

mkdir drive/MyDrive/gpg

カレントディレクトリーをそのフォルダに変更します

cd drive/MyDrive/gpg
mkdir /mnt/chromeos/drive/MyDrive/gpg

カレントディレクトリーをそのフォルダに変更します

cd /mnt/chromeos/drive/MyDrive/gpg

既にフォルダがあるときにエラーをださないようにすることもできます.以下は colabでの例です.

test -d /content/drive/MyDrive/gpg || mkdir /content/drive/MyDrive/gpg

鍵ペアの作成 #

まずは,この準備をした後,暗号と復号や,署名の検証を演習しましょう.

そこで,鍵ペアを作成します.右のイメージイラストでは,錠前が公開鍵,いわゆる鍵が秘密鍵の意図です.公開鍵は様々な人に配る(悪人が知っても良い)もので,秘密鍵は秘密に保ちます.ディスクに保存する際にも,パスフレーズを用いて暗号化して保存します.

作成には,gpg --gen-key コマンドを使います.

名前や電子メールアドレスの入力では,入力後にエンター (enter or return) キーを押します. 公開鍵と本人を結びつけるために,正しい情報を入力してください.

画像は,クリックで拡大します.

途中の

Change (N)ame, (E)mail, or (O)key/(Q)uit?

のような表記は,4つの選択肢があるので,n, e, o, q のどれか (大文字小文字は問わない) をタイプして選択してほしいという意味です.

共通鍵の場合と同様に,gpg --pinentry-mode loopback --gen-key と必要に応じてオプションを追加してください.

キーボード入力を使わない鍵ペアの生成 #

Colab で ターミナルを開かずにセルから実行する場合は,キーボード入力が難しいのであらかじめ情報をファイルに保存しておいて,それを使って鍵生成を行います.

右のような内容で設定ファイル keyconf.txt を作りましょう. 名前や,電子メールアドレスは適切に書き換えてください.
Key-Type: eddsa
Key-Curve: ed25519
SubKey-Type: ECDH
SubKey-Curve: cv25519
Name-Real: Example Taro
Name-Comment: Example Taro
Name-Email: joe@example.com
Expire-Date: 1y
Passphrase: abc
%commit
play_circle
%%shell
gpg --batch --gen-key keyconf.txt
gpg: key EF7EA0873CF6D148 marked as ultimately trusted
gpg: directory '.../.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '.../.gnupg/openpgp-revocs.d/040B3BC6D796B2B03E440E65EF7EA0873CF6D148.rev'

Chromebook端末やColab で演習中の場合は,次ページの「秘密鍵の export」に進んで,秘密鍵等の情報を Google drive に保存してから先に進んでください.

26.8.4. 秘密鍵の保存と復元

鍵の管理 #

鍵を作成した段階で,鍵の一覧を表示します.

gpg --list-keys
gpg: checking the trustdb
gpg: ...
gpg: ...
.../.gnupg/pubring.kbx
------------------------
pub   ed25519 2026-04-01 [SCA] [expires: 2027-04-01]
      040B3BC6D796B2B03E440E65EF7EA0873CF6D148
uid           [ultimate] Example Taro (Example Taro) <joe@example.com>
sub   cv25519 2026-04-01 [E] [expires: 2027-04-01]

公開鍵の export #

公開鍵を共有するために,自分の公開鍵をファイルに書き出ししょう.

gpg -a --export というコマンドを使います.

$ gpg -o studentid-pub.txt -a --export emailaddress

$ はプロンプトの意図で,gpg からタイプしてください(以下も同じ).emailaddress は鍵ペア作成時に登録した電子メールアドレス,studentidの部分は各自の学生証番号で置き換えてください.
-o studentid-pub.txt というフレーズで,studentid-pub.txtというファイルに書き出すという指示になります. 書き出したファイルを,UTOL の課題「公開鍵暗号置き場」にアップロードしましょう.

emailaddress を省略すると,手持ちのすべての鍵が出力されます.つまり,初回のexport時は自分の鍵しか持っていないので,指定を省略可能です.
エラーが出なければ成功です.Finder などで,出力されたファイルを確認しましょう.

他者の公開鍵の import #

公開鍵が書かれたファイルから,その鍵を登録するためには,gpg --import コマンドを用います.
$ gpg --import filename.txt 

UTOL の課題「公開鍵暗号置き場」から,友達の公開鍵をダウンロードします.課題一覧の画面で該当課題の右端の縦の3点 (⋮) をクリックしてメニューを開き「所属グループの提出物確認」に進みます.

先のコマンドの filename.txt をダウンロードしたファイル名で置き換えて,インポートを実行してください.

なお colab での演習では,ダウーンロードした公開鍵のファイルを, colab にアップロードしてからimport します.

26.8.1. はじめての検証

公開鍵は, import するたびに増えてゆきます

その後,登録した鍵を「信頼する」手続きをします.信頼したことを,自分の秘密鍵での署名で表すので,秘密鍵を使うためのパスフレーズを途中で聞かれるかもしれません.

$ gpg --lsign-key --yes (友達のメールアドレス) 

Colabでセルから実行する場合はキーボード入力に代えて,パスフレーズをパラメータで与えます.

$ gpg --lsign-key --yes --batch --passphrase abc --pinentry-mode loopback another-studentid-pub.txt
本当は,その公開鍵を信用して良いかどうかは別の検討が必要です.今回は授業中の演習を想定しているので割愛します.また,--yes は,指示や対象が勘違いでないかどうかの,確認を省略します.通常は使わない方が良いでしょう.
gpg --lsign-key --yes --batch --passphrase abc --pinentry-mode loopback hwb@idea.c.u-tokyo.ac.jp
pub  ed25519/B84E745EAE2A262A
     created: 2026-03-31  expires: 2029-03-30  usage: SC  
     trust: unknown       validity: unknown
sub  cv25519/486D1E5902AF0172
     created: 2026-03-31  expires: 2029-03-30  usage: E   
[ unknown] (1). HWB Project <hwb@idea.c.u-tokyo.ac.jp>

pub  ed25519/B84E745EAE2A262A
     created: 2026-03-31  expires: 2029-03-30  usage: SC  
     trust: unknown       validity: unknown
 Primary key fingerprint: A23F 6FC1 E767 F12E 9C26  D237 B84E 745E AE2A 262A

     HWB Project <hwb@idea.c.u-tokyo.ac.jp>

This key is due to expire on 2029-03-30.
Are you sure that you want to sign this key with your
key "Hyper Taro (Hyper Taro) <joe@example.com>" (07B073F38A6F0425)

The signature will be marked as non-exportable.

ディジタル署名と検証 #

テキストファイルに自分の署名を加えるには,gpg --clearsign コマンドを使います.

$  gpg -o output-filename --clearsign filename

filename は,平文と暗号文のどちらでも使えます.初めはいままでと同じ,テキストファイルの平文で試しましょう.
-o output-filename で元のファイルに署名を付加した新しいファイルを作成します. 以下は himitsu.txt に署名を付与して himitsu-signed.txt を作成する例です.署名には秘密鍵を使うため,秘密鍵を守るためのパスフレーズ入力を途中で求められます.

gpg --clearsign -o himitsu-signed.txt himitsu.txt

Colab でセルから実行する場合は,これまで同様に少し長くなります.

gpg --clearsign -o himitsu-signed.txt --batch --passphrase abc --pinentry-mode loopback himitsu.txt

できあがったファイルがどのようなものか確認してみましょう.

cat himitsu-signed.txt
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

There are three apples 🎉 日本語や絵文字も使えます.
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEEwHIB4ZLAVUgFZTU8yHlsoRC/QDIFAmnM23UACgkQyHlsoRC/
QDL0jgv+M/6tcx1zfq6kC424hzJVVwFEFQS5SAFLNCvAEVHHwP2ZJ/a8hmJ+CT5h
zqcGA0M4MDoJC9TvXPagsvwtNPEWY/N1PVPywTD/tvyHHXccs35mOXXVOxFMyh4Q
5DwcUJLKIvsa/m2WXD8CTHg1zJaexQlNH80yGXRVIWf14O483W6FX64TBKPVhz0t
BBntbW6/bYY8JgOH0GweLfnFNCfEJwkIh38JAEXL1ge4OIBOx2sYLFkmfA8ByWsW
nTYrLPKCggJYsPheEG/nwR+TEEmquPUt0D0qcAZ2fsjmnn8JptVLUMYhBnBkJnLk
R7i9C7ULxRGJF2/tRoxUM5WyR/8CPRSr6dlXOcZOBj/7TWzXQ0hya3oxdYIla9Mr
pn13Lti1ujJY/kOAgBwy+LM28jHMOw1+YXNvuo6SmrMIT0/ZeMNyLFpxZDsS9WBS
bakqwaPJtBCJsavcBHc1n7aSyWaqtq/oO4i52FejMyIsZTeax7hV69N8Ko489XU9
RZvLta4G
=lb8Y
-----END PGP SIGNATURE-----

前半がもとの平文で,後半が署名 (といっても人が読む想定ではないもの) です.

-o でファイル名を指定しないと,拡張子 .asc をつけたファイルができます. himitsu.txt なら himitsu.txt.asc です.

右のスライド中の実行例は,そのような場合です.

検証 #

電子署名の検証には gpg --verify とします. 自分で今署名したばかりのファイルを検証してみましょう.

gpg --verify himitsu-signed.txt
...
gpg: Good signature from "Hyper Taro (Hyper Taro) <joe@example.com>" [unknown]
...

Good signature (日本語モードなら 「正しい署名」 など)と出れば成功です.

署名後に平文を改ざんしたファイルを検証したため,`BAD signature` と検証に失敗する例
  • 友達から署名付きのファイル (と公開鍵) をもらって,検証してみましょう
  • 署名付きのファイルの平文の部分を編集して,署名が失敗することを確認しましょう
  • 友達に,正しい署名付きのファイルと,改竄したファイルを共有して,どちらが正しいか当ててもらいましょう

暗号化 #

公開鍵暗号の場合は,復号できるのは秘密鍵を持つ人だけです.つまり,(1) 暗号化前に送付したい人(=受信者)の公開鍵をあらかじめ入手し (2) その人を指定して暗号化する,という手順となります.

暗号化は,-ea -r emailaddress と指示します.

gpg -ea -o outputfile -r emailaddress filename
-e が暗号化 (encrypt) の指示で,-r に続くメールアドレスが宛先 (recepient) です. 自分のメールアドレスに書き換えて実行しましょう.-o outputfile で出力先を指定できます (省略すれば元ファイルに .asc をつけた名前になります).
emailaddress は受信者のメールアドレスで置き換えます. まず,自分のメールアドレス (鍵ペアを作成に登録したもの) 宛てに,himitsu.txt を暗号化しましょう. コマンドが成功すれば(エラーが出なければ),outputfile で指定した名前のファイルができています.catコマンドで確認しましょう.

Colab でセルから実行する場合は少し長くなります.

gpg -o himitsu-encrypted.txt --batch --passphrase abc --pinentry-mode loopback -ea -r joe@example.com himitsu.txt

暗号化に成功すれば,無言で終了します.

cat himitsu-encrypted.txt
-----BEGIN PGP MESSAGE-----

hQGMA8h5bKEQv0AyAQv9HLmt1agKi8vZcDPgoQ3hGLh0ql88MPGbglKJ7ic7JTyX
EhlK9crWrDs1YKC58yJc2Vwr401I2cv9eny2Bv7h5/wgQJ1LYJs35l65kFRFN3d9
...中略..
Ms9vuKi81ZPJVTnT1wajF99B2G6uRkbqkPZdPTHhom1nxxKxbPTOOszF9BhKSegW
3UnPTLN22UVkyDuA
=hdnF
-----END PGP MESSAGE-----

復号 #

復号はgpg -d コマンドです.手順は共通鍵暗号の復号 のときとコマンドは共通です.

gpg -d encrypted-filename
復号には秘密鍵を使うので,対応する秘密鍵を持つ場合だけ復号できます. 秘密鍵を使うためのパスフレーズを聞かれます.

Colab でセルから実行する場合は,これまで同様に.少し長く書きます. 以下は,無事復号された例です.

gpg --batch --passphrase abc --pinentry-mode loopback -d himitsu-encrypted.txt
gpg: encrypted with 3072-bit RSA key, ID C8796CA110BF4032, created 2026-03-30
      "Hyper Taro (Hyper Taro) <joe@example.com>"
There are three apples 🎉 日本語や絵文字も使えます.

つまり,暗号化の際に,受信者として自分を指定した場合は自分で復号できます.
受信者に他人を指定した場合は,自分では復号できません (ためしてみましょう).

FAQ #

  • 秘密鍵のパスフレーズを忘れてしまった
    • 仕方がないので,消して再度作成しましょう
    • 削除するには以下の両方の手順が必要です
      • gpg --delete-secret-key 自分のメールアドレス
      • gpg --delete-key 自分のメールアドレス
  • 友達の公開鍵を登録できたことの確認したい
    • gpg --list-keys として鍵一覧を表示します.(自分の名前とともに)友人の名前が表示されれば成功です.
  • 鍵の登録で何もメッセージが表示が表示されない
    • gpg --import filename とした際に,ファイルの中に未知の鍵がない場合に起こります.たとえば,
    • ファイル名の指定が誤っている(平文など)
    • 自分の公開鍵の書かれたファイルを指定した
    • すでに正常に登録した鍵をもう一度登録しようとした
  • 暗号化の際に「この鍵が本当に本人のものである、という兆候がありません」と表示される
    • 「偽の公開鍵」対策で,公開鍵を簡単には信用しない設定になっています.
    • gpg --lsign-key を正しく行っていれば,信頼されます.
  • 暗号化の際に「公開鍵が見つからない」旨のエラーがでる.
    • 受信者の公開鍵を入手できていない
    • gpg --import の手続きに失敗している
    • 受信者の電子メールアドレスが,公開鍵に登録されたものと異なる,など
  • 暗号化の際に「himitsu.txt が見つからない」旨のエラー
    • ファイル名の指定が誤っているので,cat himitsu.txt で中身が表示されることをまず確認しましょう.
  • その他よく分からないエラー
    • 端末を再起動して,あらためてログインしてから試すとうまくゆくことがあるかも (?)
共通鍵暗号 previous page 26.8.3. 公開鍵暗号 next page 秘密鍵の保存と復元
このサイトは開発版の はいぱーワークブック です.