暗号化の基礎
暗号化とは
暗号化は、データを当事者以外には読めない形に変換する技術です。「盗聴されても中身がわからない」状態を作ります。すべての基礎はたった3つの要素で成り立っています: 共通鍵暗号、公開鍵暗号、ハッシュ関数です。
3つの基本要素
| 要素 | 仕組み | 特徴 | 用途例 |
|---|---|---|---|
| 共通鍵暗号 | 暗号化と復号に同じ鍵を使う | 高速だが鍵の受け渡しが課題 | 通信本体の暗号化(AES) |
| 公開鍵暗号 | 公開鍵で暗号化、対になる秘密鍵でのみ復号 | 鍵配布は安全だが遅い | 鍵交換、電子署名(RSA、楕円曲線) |
| ハッシュ関数 | 元に戻せない一方向の変換 | 同じ入力は常に同じ出力。改ざん検知に使える | パスワード保存、データの整合性確認 |
初学者向けポイント
- [[HTTPS・TLS]] は「公開鍵暗号で共通鍵を安全に交換し、その後は高速な共通鍵暗号で通信する」ハイブリッド方式の代表例
- パスワードは暗号化ではなくハッシュ化して保存する。暗号化は「鍵があれば元に戻せる」が、ハッシュは元に戻せない一方向の変換だからこそパスワード保存に向く
- ハッシュ関数は SHA-256 などが代表的。「同じ入力は同じハッシュ値になる」性質を使い、ファイルの改ざん検知にも使われる
電子署名の仕組み
公開鍵暗号を逆向きに使うと電子署名になります。「秘密鍵で署名し、公開鍵で誰でも検証できる」ことで、「本人が作成したデータであること」を証明できます。[[HTTPS・TLS]] のサーバー証明書もこの仕組みの応用です。
送信者: 秘密鍵で署名を作成
受信者: 公開鍵で署名を検証 → 改ざんされていない・本人作成であることを確認
どこで暗号化するのか — 通信中と保存時
暗号化を使う場面は大きく2つに分かれます。初学者が最初に混同するところです。
- 通信中の暗号化 — ネットワークを流れている間だけ守る。[[HTTPS・TLS]] や [[SSH]]、[[VPN]] がこれにあたり、届いた先では平文に戻る
- 保存時の暗号化 — ディスクやデータベースに置いてある間を守る。ノートPCのディスク暗号化やクラウドストレージの暗号化オプションがこれ
注意したいのは、保存時の暗号化が主に効くのは媒体そのものを持ち去られたときだという点です。稼働中のサーバーに侵入され、アプリと同じ権限でデータベースへ問い合わせられた場合、返ってくるのは復号済みのデータです。「DBを暗号化しているから漏えいしても平気」は成り立ちません。だからこそ、パスワードのように元に戻す必要がない値は暗号化ではなくハッシュで持ちます([[パスワードの保存とハッシュ化]])。
鍵を守れなければ暗号は意味がない
暗号アルゴリズムの中身は公開されています。安全性は「方式を秘密にすること」ではなく、鍵だけが秘密であることに依存します。裏を返せば、鍵が漏れた時点でどんなに強力な暗号も無力です。
- 鍵の長さ — 共通鍵は AES-128 以上、公開鍵は RSA なら 2048 ビット以上が現在の目安。楕円曲線暗号はより短い鍵で同等の強度が得られる
- 鍵の置き場所 — コードや設定ファイルに直書きしない。専用の保管場所に預ける([[シークレット管理]])
- 鍵の生成に使う乱数 — 鍵やトークンは予測できない値である必要がある。一般用途の乱数を流用してはいけない
// NG: 予測可能な乱数。鍵やトークンの生成に使ってはいけない
const token = Math.random().toString(36).slice(2);
// OK: 暗号用の乱数生成器を使う
const bytes = crypto.getRandomValues(new Uint8Array(32));
開発者が気をつけること
- 自前で暗号アルゴリズムを実装しない。標準ライブラリ・実績のあるライブラリを使う
- パスワードのハッシュ化には bcrypt や Argon2 のような「意図的に遅い」専用アルゴリズムを使う(汎用ハッシュのSHA-256を単体で使うのは非推奨)
- 秘密鍵・APIキーなどの鍵管理は「外部に漏らさない」が基本原則。[[シークレット管理]] の仕組みに預けて、コードに直接書かない
つまずきやすい失敗
- エンコードを暗号化と取り違える — Base64 は誰でも元に戻せる符号化であって暗号ではありません。鍵を必要としない変換に秘匿の効果はなく、「Base64にしたから読めない」は誤りです
- 同じ入力が同じ暗号文になる — 共通鍵暗号は利用モードによって性質が変わります。古い ECB モードは同じ平文ブロックを常に同じ暗号文へ変換するため、画像を暗号化しても元の輪郭が浮かび上がります。実務では AES-GCM のように改ざん検知まで備えた認証付きのモードを選びます
- 初期化ベクトルの使い回し — 暗号化のたびに変える前提の値(IV や nonce)を固定すると、同じ鍵で暗号化した複数のデータを突き合わせて解析されます
- 暗号化しただけで安心する — 暗号化が守るのは中身の秘匿だけです。改ざんされていないかはハッシュや署名、通信相手が本物かは証明書と、担当が分かれています
暗号化の次に読む地図
暗号技術はほぼすべての分野に顔を出すため、関連する記事が広く散らばっています。目的別に3つの入口を用意しました。
3要素を1段ずつ掘る — 上の表の各行に、対応する記事があります。ハッシュと署名の詳細は [[電子署名とハッシュ]]、「その公開鍵は本当に本人のものか」を保証する仕組みは [[電子証明書とPKI]]、ハッシュの中でも特別な扱いが要るパスワードは [[パスワードの保存とハッシュ化]] です。この3本を読むと、表の各行が実装レベルまで降りてきます。
通信を暗号化している現場を見る — 同じ暗号技術が、場所を変えて何度も現れます。Webの通信は [[HTTPS・TLS]]、サーバーへのログインとファイル転送は [[SSH]]、拠点や自宅から社内へ入る経路は [[VPN]]、電波の区間を守るのは [[無線LAN(Wi-Fi)]] のWPAです。平文のまま生まれたプロトコルが後から暗号化を足された経緯を追うなら、[[FTP]] と [[メールの仕組み(SMTP・POP3・IMAP)]] のSTARTTLSが分かりやすい教材になります。
鍵とアクセス権を運用する — 鍵そのものの保管と入れ替えは [[シークレット管理]]、「誰であるか」と「何をしてよいか」の判定は [[認証と認可]]、外部サービスへ権限を預ける場面は [[OAuth・OIDC]] へ進みます。
関連技術とのつながり
- [[HTTPS・TLS]] — 公開鍵暗号と共通鍵暗号を組み合わせた実用例
- [[認証と認可]] — パスワードのハッシュ化やトークンの署名検証で暗号技術を直接使う
- [[OAuth・OIDC]] — アクセストークンの署名検証に公開鍵暗号やハッシュ(JWTの署名)を利用する
Q: 保存時の暗号化(ディスクやDBの暗号化)について、本文の説明として正しいのはどれ?
- [x] 主に媒体そのものを持ち去られたときに効き、稼働中のサーバーに侵入されると復号済みのデータが返る
- [ ] 暗号化していればサーバーに侵入されてもデータは読み取られない
- [ ] 通信中の暗号化と同じ仕組みで、届いた先でも暗号化されたままになる
解説: アプリと同じ権限で問い合わせられれば復号済みの値が返るため、「DBを暗号化しているから漏えいしても平気」は成り立ちません。
Q: Base64 エンコードについて本文の説明として正しいのはどれ?
- [ ] 鍵がなければ元に戻せない暗号化方式のひとつ
- [x] 誰でも元に戻せる符号化であり、秘匿の効果はない
- [ ] パスワード保存に推奨される一方向の変換
解説: Base64 は鍵を必要としない変換なので暗号ではありません。パスワード保存には bcrypt や Argon2 のような専用のハッシュを使います。
Q: 共通鍵暗号の利用モードとして本文が推奨しているのはどれ?
- [ ] 同じ平文ブロックが常に同じ暗号文になる ECB モード
- [x] AES-GCM のように改ざん検知まで備えた認証付きのモード
- [ ] 初期化ベクトルを固定して毎回同じ値を使うモード
解説: ECB は元データの輪郭が浮かび上がる問題があり、IV や nonce の固定も解析の手がかりを与えます。認証付きモードを選びます。