「なんとなくわかった気」で済ませていないか
HTTPS通信、SSH接続、JWTの署名検証、コードサイニング——エンジニアとして日常的に触れる技術の多くが、暗号と証明書の仕組みの上に成り立っています。しかし「SSL/TLSは通信を暗号化する」「公開鍵と秘密鍵がある」程度の理解で止まっていると、証明書エラーのトラブルシューティングや、セキュリティ要件の設計判断を迫られたときに手詰まりになります。
この記事では、共通鍵暗号と公開鍵暗号の仕組みの違いから、デジタル証明書とPKIの構造まで、実務で使える水準に引き上げることを目標に解説します。数学的な証明は省き、「なぜそう動くのか」の直感的な理解を優先します。
共通鍵暗号——速いが「鍵の配送」が弱点
共通鍵暗号(対称鍵暗号)は、暗号化と復号に同じ鍵を使う方式です。送信者と受信者が事前に同じ鍵を共有し、その鍵でデータを暗号化・復号します。代表的なアルゴリズムはAES(Advanced Encryption Standard)で、現代のシステムで最も広く使われている共通鍵暗号です。
共通鍵暗号の最大の強みは処理速度です。公開鍵暗号と比べて桁違いに高速なため、大量のデータを暗号化する場面(ファイル暗号化、ストリーム通信など)では共通鍵暗号が使われます。
ただし致命的な弱点があります。それが「鍵配送問題」です。送信者と受信者が同じ鍵を持たなければ通信できませんが、その鍵をどうやって安全に相手に渡すのかという問題です。インターネット上でそのまま鍵を送れば、途中で盗まれた瞬間に暗号の意味がなくなります。この問題を解決したのが、後述する公開鍵暗号です。
公開鍵暗号——鍵配送問題を解決した革命的な発明
公開鍵暗号(非対称鍵暗号)は、「公開鍵」と「秘密鍵」という数学的にペアになった2つの鍵を使う方式です。公開鍵で暗号化したデータは、対応する秘密鍵でしか復号できません。逆に秘密鍵で署名したデータは、対応する公開鍵でしか検証できません。
公開鍵はその名の通り誰にでも公開できます。秘密鍵は自分だけが持ちます。これによって鍵配送問題が解決されます。「相手の公開鍵で暗号化して送れば、秘密鍵を持つ相手しか復号できない」——この仕組みによって、事前に安全なチャネルで鍵を共有しなくても、安全な通信が実現できます。
代表的なアルゴリズムはRSAとECC(楕円曲線暗号)です。RSAは長年標準として使われてきましたが、近年は鍵長が短くても同等の安全性を持つECCへの移行が進んでいます。
2方式の特性比較
| 項目 | 共通鍵暗号(AESなど) | 公開鍵暗号(RSA/ECCなど) |
|---|---|---|
| 鍵の種類 | 1種類(送受信者で共有) | 2種類(公開鍵・秘密鍵) |
| 処理速度 | 高速 | 低速(共通鍵の数百〜千倍遅い) |
| 鍵配送問題 | あり(事前共有が必要) | なし(公開鍵を配布するだけ) |
| 主な用途 | 大量データの暗号化 | 鍵交換・デジタル署名 |
| 代表アルゴリズム | AES-128/256 | RSA-2048、ECDSA、ECDH |
ハイブリッド暗号——2方式の弱点を補い合う
実際のTLS通信では、共通鍵暗号と公開鍵暗号を組み合わせた「ハイブリッド暗号」が使われています。それぞれの弱点を補い合う巧妙な設計です。
流れはこうです。まず公開鍵暗号を使って「セッション鍵(共通鍵)」を安全に交換します。その後は高速な共通鍵暗号でデータ本体を暗号化します。公開鍵暗号の遅さは「鍵交換だけ」に使い、実際の通信データには共通鍵暗号を使うことで、両方の利点を活かしています。
HTTPSの通信を確立するTLSハンドシェイクがまさにこの仕組みです。ブラウザとサーバーが公開鍵暗号でセッション鍵を合意し、以降の通信はAESなどで暗号化されます。
デジタル署名——「本人性」と「改ざん検知」を同時に実現
公開鍵暗号のもう一つの重要な応用が「デジタル署名」です。暗号化とは逆の向き——秘密鍵で署名し、公開鍵で検証する——という使い方で、以下の二つを同時に証明できます。
- 本人性の証明:秘密鍵を持つ本人だけが署名できるため、なりすましを防げます。
- 改ざん検知:署名後にデータが1バイトでも変わると検証が失敗するため、途中の改ざんを検出できます。
実際の署名プロセスでは、データ全体に署名するのではなく、データのハッシュ値(SHA-256などで生成した固定長のダイジェスト)に対して署名します。ハッシュを使うことで処理量を減らしつつ、データの一意性を保証できます。
JWTの署名検証、GitHubのコミット署名(GPG署名)、コードサイニング証明書によるソフトウェア署名——これらはすべてデジタル署名の応用です。
デジタル証明書とPKI——「その公開鍵は本物か」を保証する仕組み
公開鍵暗号の前提として「相手の公開鍵が本物かどうか」を確認する必要があります。公開鍵はインターネット上に配布できますが、悪意ある第三者が偽の公開鍵を配布して中間者攻撃を行う可能性があります。これを防ぐのがデジタル証明書です。
デジタル証明書(X.509証明書)は、「この公開鍵はこのドメイン(または組織)のものである」という事実を、信頼できる第三者機関(CA:認証局)が保証した電子文書です。証明書には以下の主な情報が含まれています。
- サブジェクト(証明対象のドメイン名・組織名)
- 公開鍵
- 有効期限
- 発行者(CA)の情報
- CAによるデジタル署名
PKI(公開鍵基盤)の信頼チェーン
証明書の信頼は「信頼チェーン(Chain of Trust)」によって成立しています。ルートCA(ルート認証局)を頂点とし、中間CA、エンドエンティティ証明書(サーバー証明書など)という階層構造になっています。
ブラウザやOSにはあらかじめ信頼するルートCAの証明書がインストールされており、このルートCAが署名した中間CA、中間CAが署名したサーバー証明書——という署名の連鎖をたどることで、サーバー証明書の正当性を検証します。証明書エラーが出る原因のほとんどは、この信頼チェーンのどこかが断ち切られていることにあります。
証明書エラーの主な原因
| エラーの種類 | 主な原因 | 対処方法 |
|---|---|---|
| 有効期限切れ | 証明書の更新忘れ | 証明書を更新・自動更新の設定 |
| ホスト名の不一致 | アクセスしたドメインと証明書のCNが異なる | 正しいドメインの証明書を取得 |
| 自己署名証明書 | CAに署名されていない証明書を使用 | 信頼できるCAの証明書を取得 |
| 中間CA証明書の欠落 | サーバーが中間証明書を送っていない | サーバー設定で中間証明書を含めて送信 |
| 失効済み証明書 | CRLまたはOCSPで失効確認されている | 新しい証明書を発行 |
エンジニアが実務で意識すべきポイント
これらの知識を踏まえ、実務での判断に直結するポイントをいくつか整理します。
まず証明書の管理です。Let's Encryptのような無料CAを使えば自動更新も設定できますが、有効期限の監視は必ず仕組み化しましょう。本番環境での証明書失効は即座にサービス障害につながります。
次に鍵長の選択です。RSAを使う場合、現在の推奨は2048ビット以上、可能であれば4096ビットです。ECCを選ぶなら256ビット(P-256曲線)で十分な安全性が得られます。古いシステムとの互換性が不要であればECCを選ぶほうが効率的です。
最後にハッシュアルゴリズムの選択です。SHA-1はすでに非推奨です。証明書や署名にはSHA-256以上を使うことが現代のセキュリティ要件の最低ラインです。SHA-1を使ったシステムがまだ残っている場合は、早急な移行計画を立てるべきです。
暗号と証明書の仕組みを理解していると、セキュリティ設計のレビューやトラブルシューティングで「なぜそうなっているか」を根拠を持って判断できるようになります。コードの書き方と同様に、セキュリティの基礎はエンジニアとしての判断力の土台です。