【証明書入門 第2回】暗号の基礎 ― 共通鍵・公開鍵・鍵交換・ハッシュ・署名を図で理解する

証明書・PKI
スポンサーリンク
スポンサーリンク

「公開鍵で暗号化して、秘密鍵で署名して…あれ、逆でしたっけ?」
「HTTPSって、RSAでデータを暗号化しているんですよね?」

証明書の話をしていると、こうした疑問によく出会います。実は、後者は間違いです。今のTLSで実際のデータを暗号化しているのは、RSAではなく共通鍵暗号です。

第1回では、TLSが盗聴・改ざん・なりすましの3つの脅威を、別々の部品で守っていることを見ました。第2回では、その部品を1つずつ見ていきます。数式は使わず、「どの部品が何を守るか」に絞って説明します。


共通鍵暗号(AES)

共通鍵暗号は、暗号化と復号に同じ鍵を使う方式です。1本の鍵で開け閉めする金庫を、送る側と受け取る側が同じ鍵で使うイメージです。

送信者と受信者が同じ共通鍵を持ち、「10:00 作業開始」をAESで暗号化した暗号文は、鍵を持たない盗聴者には読めないことを示す図

処理が軽く高速なため、TLSでもディスクの暗号化(BitLockerなど)でも、データそのものの暗号化は今も共通鍵暗号が担っています。

  • 現在の標準はAES(2001年にFIPS 197として標準化)
  • データを128ビット(16バイト)ずつのブロックに区切って暗号化するブロック暗号
  • 鍵の長さは128・192・256ビットから選ぶ
  • 多くのCPUがAES専用の命令を持ち、非常に高速に処理できる

以前使われたDESは鍵が短すぎて破られ、3DES(トリプルDES)もNISTが2023年末で暗号化への使用を認めなくなりました。

共通鍵暗号の弱点は、同じ鍵を相手とどうやって安全に共有するかという点です(後で説明します)。


ブロック暗号の利用モードと認証付き暗号

AESのようなブロック暗号は、どうブロックをつなぐか(利用モード)で性質が大きく変わります。

元の画像をECBで暗号化すると輪郭が残り、GCMでは砂嵐になることと、AES-GCMが平文・鍵・ナンスから暗号文と16バイトのタグを作り、受信側でタグが合わなければ破棄することを示す図
方式仕組み特徴・注意使いどころ
ECBブロックごとに単独で暗号化同じ平文のブロックは同じ暗号文になり、模様が残る使わない
CBC前の暗号文ブロックと混ぜてから暗号化改ざんを検知できず、別に MAC が要る。パディングを悪用する攻撃があったTLS 1.2 以前、古い製品
CTRカウンターの値を暗号化し、平文と XOR並列に処理でき速い。改ざん検知はないGCM などの部品
GCM(AES-GCM)CTR + 改ざん検知用のタグ認証付き暗号(AEAD)。同じ鍵でナンス(使い捨ての値)を再利用すると破綻するTLS 1.2/1.3 の主流、IPsec
ChaCha20-Poly1305ストリーム暗号 + MAC(RFC 8439)AEAD。AES 専用命令のない機器でも速いTLS 1.3、スマートフォン、WireGuard
XTSディスク上の位置ごとに値を変えて暗号化保存データ向け。改ざん検知はないディスクの暗号化

図のペンギンのように、ECBは模様が漏れるので使いません。NISTの草案(SP 800-131A Rev.3)は、ECBを暗号化に使うのをやめる案です。

今の主流は認証付き暗号(AEAD)です。暗号化と改ざん検知を1回の処理で行い、暗号文と一緒にタグを作ります。受け取った側でタグが合わなければ、そのデータは破棄されます。第1回の「完全性(書き換えられていない)」を守っているのが、このタグです。

TLS 1.3では、AEADの暗号スイート(TLS_AES_128_GCM_SHA256、TLS_AES_256_GCM_SHA384、TLS_CHACHA20_POLY1305_SHA256など)しか使えません。


鍵配送の問題

共通鍵暗号を使うには、通信の前に相手と同じ鍵を持っていなければなりません。問題は、その鍵をどう安全に渡すかです。

メールで送ると経路で鍵ごと盗まれ、パスワードを別のメールで送っても同じ経路で盗聴者は両方見られ、会って手渡しはネット上の相手とはできないことと、相手ごとに鍵が要り100人なら4,950本になることを示す図
  • メールで送る:メールの経路が安全でない限り、鍵ごと盗まれる
  • 暗号化ZIPのパスワードを別のメールで送る:同じ経路を2回使うだけで、安全性はほとんど変わらない
  • 会って手渡しする:安全だが、インターネット上の見知らぬ相手とは不可能

さらに、相手ごとに別の鍵が必要なので、n人がお互いに通信するにはn(n−1)/2本の鍵が要り、100人なら4,950本になります。

つまり、鍵を安全に渡すには、すでに安全な通信路が必要という堂々巡りに陥ります。これを鍵配送問題と呼びます。この問題を解いたのが、次の公開鍵暗号と鍵交換です。


公開鍵暗号(RSA・楕円曲線)

公開鍵暗号は、対になった2つの鍵を使います。

  • 公開鍵:誰に配ってもよい
  • 秘密鍵:本人だけが持つ

公開鍵で暗号化したデータは、対になる秘密鍵でしか復号できません。

受信者が鍵ペアを作って公開鍵を配り(盗聴者にも届く)、送信者が公開鍵で暗号化した暗号文は公開鍵では開けられず、受信者の秘密鍵でだけ復号できることを示す図

南京錠にたとえると、公開鍵は誰でも閉められる開いた南京錠、秘密鍵はそれを開けられる唯一の鍵です。閉める鍵は配り、開ける鍵は手元から出さない。これなら復号用の鍵を渡す必要がなく、鍵配送問題を避けられます。

代表的な方式は2つです。

  • RSA(1977年):大きな数の素因数分解の難しさを使う
  • 楕円曲線暗号(ECC):楕円曲線上の計算の難しさを使う(P-256、Curve25519など)。RSAよりずっと短い鍵で同じ強さが得られる(RSA 3072ビット ≒ 楕円曲線256ビット)

ただし公開鍵暗号は、共通鍵暗号より桁違いに遅く、RSAで一度に暗号化できるのは鍵の長さより短いデータ(数百バイト)だけです(第3回で試します)。そのため実際には、鍵の受け渡しと署名に使います。冒頭の「HTTPSはRSAでデータを暗号化している」が間違いなのは、このためです。


鍵交換(DH・ECDHE)

現在のTLSで共通鍵を共有する方法が、鍵交換です。

AさんとBさんが共通の黄色に自分だけの秘密の色を混ぜ、混ぜた橙と緑を交換し、受け取った色に自分の秘密の色を足すと2人とも同じ茶色になり、盗聴者には橙と緑しか見えないことを示す図

Diffie-Hellman(DH)鍵交換(1976年)では、双方がそれぞれ秘密の値を作り、そこから計算した公開用の値だけを交換します。受け取った相手の値と自分の秘密の値を組み合わせると、両側で同じ値が得られます。

絵の具にたとえると、こうです。

  1. 共通の色(黄)を決める
  2. それぞれが自分だけの秘密の色を混ぜる(黄+赤=橙、黄+青=緑)
  3. 混ぜた色(橙と緑)を交換する
  4. 受け取った色に、もう一度自分の秘密の色を混ぜると、2人とも同じ茶色になる

混ぜた色から元の色は取り出せないので、盗聴者は同じ色を作れません。

楕円曲線で行うものをECDH、接続のたびに使い捨ての値を使うものをECDHE(EはEphemeral:一時的)と呼び、TLS 1.3ではX25519などのECDHEが標準です。

ただし、DHは相手を確かめません。第1回の中間者攻撃を防ぐには、証明書と署名が必要です。


前方秘匿性とTLSのハイブリッド構成

TLS 1.2までは、クライアントが作った鍵の材料を、サーバーのRSA公開鍵で暗号化して送る方式(RSA鍵交換)も使われていました。

RSA鍵交換では攻撃者が通信を録画しておき数年後にサーバーの秘密鍵が漏れると過去の通信がすべて読まれるが、ECDHEでは使い捨ての値を捨てるので秘密鍵が漏れても録画は読めないことと、今のTLSはECDHE・証明書と署名・AES-GCMの3つを組み合わせることを示す図

この方式では、攻撃者が暗号化された通信を録画しておき、後でサーバーの秘密鍵を手に入れると、過去の通信をすべて復号できます。

一方ECDHEは、接続ごとの秘密の値を使い終わったら捨てるため、後から秘密鍵が漏れても過去の通信は読めません。この性質を前方秘匿性(Forward Secrecy)と呼びます。TLS 1.3はRSA鍵交換を廃止しました。漏れて困る鍵を、そもそも残さないという考え方です。

現在のTLSは、次の3つを組み合わせたハイブリッド構成です。

  1. 鍵交換(ECDHE)で共通鍵の材料を作る
  2. 証明書と署名で相手が本物かを確かめる
  3. 以後のデータは共通鍵の認証付き暗号(AES-GCM等)で守る

公開鍵の技術は最初だけ使い、実データは共通鍵で守ります。

ポイント
・RSA鍵交換は、秘密鍵が漏れると録画された過去の通信まで読まれる
・ECDHEは使い捨ての値を捨てるので、過去の通信が守られる
・TLSは「鍵交換+証明書と署名+共通鍵のAEAD」の組み合わせ


ハッシュ関数(SHA-2・SHA-3)

ハッシュ関数は、任意の長さのデータから、決まった長さの値(ハッシュ値)を計算する関数です。

hello worldとhello Worldの1文字の違いでSHA-256のハッシュ値がまったく別の値になることと、一方向性・衝突困難性・1文字で大きく変わる・出力は固定長という4つの性質を示す図

暗号に使うハッシュ関数には、4つの性質が求められます。

  1. 一方向性:ハッシュ値から元のデータを求められない
  2. 衝突困難性:同じハッシュ値になる別のデータを見つけられない
  3. 元のデータが1文字違うだけで、ハッシュ値がまったく変わる
  4. 入力の長さによらず、出力の長さが一定

現在の標準はSHA-2(SHA-256・SHA-384・SHA-512など)で、構造の異なるSHA-3(2015年、FIPS 202)も標準化されています。ダウンロードしたファイルの照合、証明書のフィンガープリント、署名の前処理などに使います。

なお、パスワードの保存には、わざと計算を遅くした専用の方式(PBKDF2、bcrypt、Argon2など)を使います。


MD5・SHA-1が使えない理由

衝突困難性が破れると、何が起きるのでしょうか。

年出来事意味
2004MD5 で衝突(同じハッシュ値になる別のデータ)が見つかる衝突困難性が破れた
2008MD5 の衝突を使い、ブラウザーが信頼する偽の CA 証明書を作れることを研究者が実証証明書の偽造が現実になった
2012マルウェア Flame が MD5 の衝突で Microsoft の署名を偽装し、Windows Update を装って広がる実際の攻撃に使われた
2017SHAttered:SHA-1 で初の衝突。同じハッシュ値の別の PDF を2つ公開(Google と CWI)SHA-1 も実用的に破れた
2017主要なブラウザーが SHA-1 で署名されたサーバー証明書を信頼しなくなる公開証明書から SHA-1 が消える
2020SHA-1 is a Shambles:選択プレフィックス衝突で PGP の鍵を偽造(計算費用は約4.5万ドル相当)狙った内容で偽造できる
2026CA/Browser Forum の基準で、証明書と CRL への SHA-1 署名を9月15日までに全廃公開 PKI から退場

衝突が作れると、「無害な文書に署名させ、同じハッシュ値の有害な文書にその署名を流用する」ことができます。MD5・SHA-1は偶発的な破損の確認なら今も動きますが、改ざん対策や署名にはSHA-256以上を使います。


MACとデジタル署名

ここで大事な落とし穴があります。ハッシュ値を添えるだけでは、改ざんは防げません。攻撃者は本文を書き換えたうえで、ハッシュ値も計算し直して差し替えられるからです。

ハッシュ値を添えるだけでは攻撃者が値も計算し直して差し替えられること、MAC(HMAC)は共通鍵を使うので鍵のない攻撃者は作れないが2人のどちらが作ったかは区別できないこと、デジタル署名は秘密鍵で作り公開鍵で誰でも検証できることを示す図

そこで、鍵を持つ人にしか作れない値を添えます。

  • MAC(メッセージ認証コード):送る側と受け取る側が同じ共通鍵を持ち、本文と鍵から値を計算する。代表がHMAC(RFC 2104)。鍵を知らない攻撃者は正しい値を作れないが、鍵を持つ2人のどちらが作ったかは区別できない
  • デジタル署名:送る側が本文のハッシュ値に自分の秘密鍵で署名し、受け取る側は公開鍵で検証する。秘密鍵の持ち主にしか作れないので、第三者にも作成者を示せる

なお、「署名=ハッシュを秘密鍵で暗号化」というのはRSAだけに当てはまるたとえで、ECDSAなどには当てはまりません。冒頭の「公開鍵で暗号化、秘密鍵で署名」は正しい理解です。

ハッシュ・MAC・署名の違い

項目ハッシュMAC(HMAC)デジタル署名
使う鍵なし共通鍵(2人が同じ鍵を持つ)秘密鍵で署名、公開鍵で検証
作れる人誰でも鍵を持つ全員秘密鍵の持ち主だけ
検証できる人誰でも鍵を持つ人だけ公開鍵を持つ誰でも
分かること偶然の破損改ざんの有無改ざんの有無と作成者
第三者への証明できないできないできる
速さ速い速い遅い
主な使われ方ファイルの照合、フィンガープリントTLS の鍵の導出と確認、API の認証証明書、TLS のハンドシェイク、コード署名

違いは「誰が作れるか」と「誰が確かめられるか」です。HMACは共通鍵を使うMACで、公開鍵暗号を使う署名とは別の技術です。TLS 1.3では、証明書とハンドシェイクの確認に署名を、鍵の導出(HKDF)とハンドシェイク最後の確認(Finished)にHMACを使います。


署名方式(RSA・ECDSA・Ed25519)

方式基になる仕組み特徴使える場面・注意
RSA(PKCS#1 v1.5)RSA最も古く、互換性が高い公開証明書の署名で今も主流。TLS 1.3 のハンドシェイクの署名には使わない(古い機器のクライアント証明書向けの例外:RFC 9963)
RSA-PSSRSAランダムな値(ソルト)を加える新しい形式。安全性の証明があるTLS 1.3 で RSA の鍵を使うときの署名
ECDSA楕円曲線(P-256 等)鍵と署名が小さく速い。署名ごとに使い捨ての乱数が必要公開証明書で使える。乱数を使い回すと秘密鍵が漏れる
Ed25519(EdDSA)楕円曲線(Curve25519 系)速く、乱数に頼らない(決定的)。実装の誤りが起きにくいSSH の鍵、ソフトウェアの署名。公開の TLS 証明書には使えない
ML-DSA格子(PQC)量子計算機でも破れないとされる。署名が数KBと大きいFIPS 204(2024年)。証明書での利用はこれから

CA/Browser Forumの基準で、公開のサーバー証明書に使える鍵は、RSA(2048ビット以上)とECDSA(P-256・P-384・P-521)だけです。OpenSSL 3.5で実際に作った署名の大きさは、RSA 3072ビットが384バイト、ECDSA P-256が約70バイト、Ed25519が64バイト、ML-DSA-65が3,309バイトでした。


鍵長と強度

セキュリティ強度共通鍵・ハッシュRSA・DH/楕円曲線扱い(NIST・CRYPTREC)
80ビット以下2TDEA、SHA-1(署名用)RSA 1024/160ビット使用不可
112ビットSHA-224RSA 2048/P-2242030年まで。新しく作るなら避ける
128ビットAES-128、SHA-256RSA 3072/P-256、X255192031年以降の最低ライン
192ビットAES-192、SHA-384RSA 7680/P-384長期の保護向け
256ビットAES-256、SHA-512RSA 15360/P-521長期の保護向け

(基準:NIST SP 800-57 Part 1 Rev.5(2020年)、SP 800-131A Rev.2(2019年)、CRYPTREC暗号リスト(2026年3月の改定でML-KEMなどのPQCリストを新設)と「暗号強度要件(アルゴリズム及び鍵長選択)に関する設定基準」)

  • RSA 2048は112ビット強度で、新しく暗号化・署名に使えるのは2030年まで。これから作る鍵はRSA 3072以上か、P-256以上を選ぶ
  • NISTの草案(SP 800-131A Rev.3、IR 8547)は、2030年末で112ビットを、2035年でRSA・楕円曲線そのものを使用不可とする案を示している

乱数

暗号の安全性は、鍵やナンスが予測できない乱数から作られていることを前提にしています。

OSの乱数生成器から鍵ペア・ECDHEの使い捨ての値・ハンドシェイクの乱数・ECDSAの署名ごとの値・ナンスが作られることと、2008年のDebianのOpenSSLで鍵が数万通りしかなかった事例、2010年のゲーム機のECDSAで同じ値を使い回して秘密鍵が計算された事例を示す図

TLSでも、鍵ペア、ECDHEの使い捨ての値、ECDSAの署名ごとの値など、あらゆる所で乱数を使います。乱数が偏ると、方式や鍵長が正しくても安全性は崩れます。

  • 2008年:DebianのOpenSSLの修正ミスで乱数の元がほぼプロセスIDだけになり、作られる鍵が数万通りに限られた
  • 2010年:ゲーム機がECDSAの署名に毎回同じ値を使っていたため、署名から秘密鍵が計算された
  • 起動直後の組み込み機器などでは、乱数の元が足りず鍵が重複した例もある

乱数にはOSの暗号用の乱数生成器(Linuxのgetrandom()、WindowsのBCryptGenRandom)を使い、rand()やPowerShellのGet-Randomは使いません。


耐量子計算機暗号(PQC)

最後に、少し先の話です。実用的な量子計算機が実現すると、RSA・DH・楕円曲線暗号など今の公開鍵暗号は解読されると考えられています。共通鍵暗号とハッシュへの影響は比較的小さく、長い鍵(AES-256など)で対応できます。

攻撃者が2026年に通信を録画しておき、将来の量子計算機で解読する攻撃と、鍵交換を今PQCにすれば録画されても読めないことと、2026年9月時点の移行状況(鍵交換はX25519MLKEM768で利用中、署名・証明書はこれから、共通鍵・ハッシュは鍵を長くすれば対応)を示す図

差し迫った問題は、今の通信を録画して、将来の量子計算機で解読する攻撃(Harvest Now, Decrypt Later)です。長く秘密にしたい情報のために、鍵交換を先に移行する必要があります。署名は、解読できる日の前に切り替えれば間に合います。

  • NISTは2024年8月に、鍵共有のML-KEM(FIPS 203)、署名のML-DSA(FIPS 204)とSLH-DSA(FIPS 205)を標準化
  • TLSでは、X25519とML-KEM-768を組み合わせたハイブリッド鍵交換X25519MLKEM768が、主要なブラウザーやOpenSSL 3.5以降で使われている(第7回)
  • 署名と証明書の移行はこれから

急ぐのは鍵交換。録画された通信は後から守れない、と覚えておきましょう。


考えてみよう

  1. 社内に「ZIPファイルを暗号化して送り、パスワードを別のメールで送る」運用があるとしたら、それは鍵配送問題をどの程度解決しているでしょうか。
  2. 「SHA-256のハッシュ値を一緒に配布しているので、改ざんされても分かる」という説明は正しいでしょうか。ハッシュ値をどこから入手するかに注目して考えてください。
  3. 手元の機器やサーバーで、RSA 1024ビットの鍵、SHA-1の署名、TLS 1.2のRSA鍵交換を使っているものはありませんか。2030年に向けて何を替える必要がありますか。

ヒント:この記事の「ハッシュ・MAC・署名の違い(作れる人・検証できる人)」「前方秘匿性」「鍵長と強度」の表が手がかりです。


まとめ

  • 実データは共通鍵暗号(AES-GCMなどのAEAD)で暗号化する。ECBは使わない
  • 共通鍵には鍵配送問題がある。解決するのが公開鍵暗号と鍵交換
  • 今のTLSはECDHE+証明書と署名+AEAD。ECDHEで前方秘匿性が得られる
  • ハッシュ値だけでは改ざんを防げない。作成者まで示せるのはデジタル署名
  • MD5・SHA-1は使わない。新しい鍵はRSA 3072以上かP-256以上
  • PQCは鍵交換から移行が始まっている

次回は、ここで見た部品を、opensslとPowerShellで実際に動かしてみます。


連載「証明書入門」全11回

  1. なぜ証明書が必要か
  2. 暗号の基礎(この記事)
  3. openssl・PowerShellで試す
  4. X.509証明書の中身
  5. PKIと信頼の仕組み
  6. 証明書の種類と発行
  7. TLSの仕組み
  8. ライフサイクルと自動化
  9. 社内PKIとクラウド
  10. 証明書トラブルシュート
  11. 証明書の設計演習

コメント

タイトルとURLをコピーしました