暗号の教科書は、たいていアリスとボブという二人から始まります。アリスはボブに秘密の手紙を送りたい。アリスが鍵をかけ、ボブが鍵を開け、イブが途中で盗み聞きを試みる。図の中では鍵のマークが右へ左へ飛び交い、三往復目あたりで、どの鍵が誰のものだったか分からなくなる。ページを戻る。また分からなくなる。そっと本を閉じる。覚えのある方も多いと思います。
三往復目で、どの鍵が誰のものか分からなくなる。
この連載では、その本は閉じたままで構いません。代わりにターミナルを開きます。
暗号は、読むより触るほうが早い
暗号が難しいのは、目に見えない概念が積み上がっていくからです。ハッシュ、共通鍵、公開鍵、署名、証明書。どれも手応えのないまま、次の章では前の章の理解を前提にされる。
ところが実物は、あなたの手元にあります。openssl というコマンドです。ハッシュを取る、ファイルを暗号化する、鍵のペアを作る、証明書を発行する、HTTPS の中身を覗く。教科書の登場人物は、ほぼ全員このコマンド一本で呼び出せます。
たとえば入力を1文字変えると、ハッシュ値は原形をとどめないほど変わります。文章で読めば「そうですか」で終わる性質ですが、自分のターミナルで目撃すると10秒で腑に落ちます。この連載がやりたいのは、その10秒の積み重ねです。
全6回で何をやるか
- ハッシュ関数:「改ざんされていない」を証明します。
- 共通鍵暗号(AES):ファイルを暗号化して、鍵の受け渡しに困ります。
- 公開鍵暗号(RSA):鍵を2つに分けて、前回の困りごとを解決します。
- デジタル署名:「本人が書いた」を証明します。
- 証明書と PKI:自分で証明書を発行して、ブラウザに警告されます。
- TLS/HTTPS:ここまでの部品を、1本の通信に組み立てます。
第2回でわざと困り、第3回で解決します。第1回のハッシュと第3回の鍵は、第4回で合流します。最終回では第5回で発行した証明書を使って、手元に 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文字が、出力のすべてを変える様子を自分の手で確かめます。
アリスには、連載の後半で改めて登場してもらいます。そのころにはその鍵は、図の中の記号ではなく、あなたのターミナルの中のファイルになっています。
