暗号の教科書は、たいていアリスとボブという二人から始まります。アリスはボブに秘密の手紙を送りたい。アリスが鍵をかけ、ボブが鍵を開け、イブが途中で盗み聞きを試みる。図の中では鍵のマークが右へ左へ飛び交い、三往復目あたりで、どの鍵が誰のものだったか分からなくなる。ページを戻る。また分からなくなる。そっと本を閉じる。覚えのある方も多いと思います。

教科書の図は、だいたいこう。
鍵 鍵 鍵 ? ? アリス ボブ イブ 鍵 鍵 鍵 ? ? アリス ボブ イブ

三往復目で、どの鍵が誰のものか分からなくなる。

この連載では、その本は閉じたままで構いません。代わりにターミナルを開きます。

暗号は、読むより触るほうが早い

暗号が難しいのは、目に見えない概念が積み上がっていくからです。ハッシュ、共通鍵、公開鍵、署名、証明書。どれも手応えのないまま、次の章では前の章の理解を前提にされる。

ところが実物は、あなたの手元にあります。openssl というコマンドです。ハッシュを取る、ファイルを暗号化する、鍵のペアを作る、証明書を発行する、HTTPS の中身を覗く。教科書の登場人物は、ほぼ全員このコマンド一本で呼び出せます。

たとえば入力を1文字変えると、ハッシュ値は原形をとどめないほど変わります。文章で読めば「そうですか」で終わる性質ですが、自分のターミナルで目撃すると10秒で腑に落ちます。この連載がやりたいのは、その10秒の積み重ねです。

全6回で何をやるか

  1. ハッシュ関数:「改ざんされていない」を証明します。
  2. 共通鍵暗号(AES):ファイルを暗号化して、鍵の受け渡しに困ります。
  3. 公開鍵暗号(RSA):鍵を2つに分けて、前回の困りごとを解決します。
  4. デジタル署名:「本人が書いた」を証明します。
  5. 証明書と PKI:自分で証明書を発行して、ブラウザに警告されます。
  6. TLS/HTTPS:ここまでの部品を、1本の通信に組み立てます。

第2回でわざと困り、第3回で解決します。第1回のハッシュと第3回の鍵は、第4回で合流します。最終回では第5回で発行した証明書を使って、手元に HTTPS サーバーを立てる。読み終わるころには、アドレスバーの鍵マークを、部品から積み上げて説明できるようになっているはずです。

6回が、どうつながるか。
合流 困って、解決 合流 保証印に 証明書で立てる 本文を運ぶ 第1回 ハッシュ 第2回 共通鍵 第3回 公開鍵 第4回 署名 第5回 証明書 第6回 TLS/HTTPS 困って、解決 合流 合流 保証印に 証明書で立てる 本文を運ぶ 第1回 ハッシュ 第2回 共通鍵 第3回 公開鍵 第4回 署名 第5回 証明書 第6回 TLS/HTTPS

矢印は、前の回で作った部品を、あとの回が使う向き。

macOS の openssl は LibreSSL なので、OpenSSL 3系に入れ替える

今回のハンズオンはここからです。いま入っている openssl を確かめます。

openssl version

Mac の場合、何もしていなければ、おおよそこう返ってきます(バージョンの数字は OS によって前後します)。

LibreSSL 3.3.6

OpenSSL を確かめたはずが、別の名前が返ってきました。macOS に最初から入っている /usr/bin/openssl の中身は、OpenSSL から分岐した互換実装の LibreSSL です。基本的なコマンドはおおむね同じように動きますが、使えるオプションや出力の細部が違います。連載の途中で「記事と画面が違う」と悩むのは避けたいので、本連載は OpenSSL 3系に統一します。

Homebrew で入れます。

brew install openssl

入れたら、どちらの openssl が呼ばれるかを確認します。

which openssl
# /opt/homebrew/bin/openssl

openssl version
# OpenSSL 3.6.3 9 Jun 2026 (Library: OpenSSL 3.6.3 9 Jun 2026)

which の結果が /usr/bin/openssl のままなら、PATH で Homebrew のディレクトリ(Apple Silicon なら /opt/homebrew/bin、Intel なら /usr/local/bin)が優先されていません。Homebrew 公式のセットアップ手順にある eval "$(/opt/homebrew/bin/brew shellenv)" をシェルの設定ファイルに追加して、ターミナルを開き直してください。

バージョンの数字は手元と違っていて構いません。3で始まっていれば、この連載のコマンドはそのまま進められます。Linux はたいてい最初から OpenSSL が入っているので、openssl version で OpenSSL と表示されればそのままどうぞ。

openssl rand で乱数を作る

環境が整ったところで、今回はもう一つだけ打って終わります。

openssl rand -hex 16
# 4c4194ec93a02d9e8d897b50c3c481c3

rand は乱数を作るコマンドです。末尾の 16 は長さの指定で、16バイトぶんの乱数を作ります。-hex は表示形式の指定です。乱数そのものは画面に出せないバイナリなので、0〜9 と a〜f を使う16進数に置き換えて表示します。1バイトが2文字になるため、画面に並ぶのは32文字です。実行するたびに違う値が出ます。

地味です。ただ、暗号という建物は、この地味な一行の上に建っています。この先の連載で作る鍵も、暗号文に混ぜるソルトも、素性はすべて乱数です。予測できない乱数が作れなければ、どれだけ頑丈な暗号を使っても、鍵そのものを当てられて終わります。錠前がいくら立派でも、番号が誕生日なら開いてしまうのと同じです。

余談ですが、この一行はそのままパスワード生成器としても使えます。-hex 16 の 16 を増やせば、好きなだけ長くなります。

今日作った乱数とは、第3回で鍵を作るときに再会します。次回はハッシュ関数です。入力の1文字が、出力のすべてを変える様子を自分の手で確かめます。

アリスには、連載の後半で改めて登場してもらいます。そのころにはその鍵は、図の中の記号ではなく、あなたのターミナルの中のファイルになっています。