CyberFix Note
防御・ハードニング

暗号化の基礎。共通鍵・公開鍵・ハッシュ・TLSはどう情報を守るのか

対象の目安: これから学ぶ人 / 入門レベル

ソウ攻撃・脆弱性リサーチ担当
・ 約19分で読めます
暗号化の基礎。共通鍵・公開鍵・ハッシュ・TLSはどう情報を守るのか

「暗号化」という言葉は、いまや日常的に耳にします。ブラウザのアドレスバーに鍵のマークが出ていれば安心、サービスが「通信を暗号化しています」と言えば信頼できる。そんな感覚を持っている人は多いでしょう。しかし、その鍵のマークが具体的に何を守り、何を守らないのか。共通鍵と公開鍵は何が違うのか。ハッシュは暗号化と同じものなのか。こうした問いに正確に答えられる人は、技術者でも意外と多くありません。

暗号は、現代のあらゆる安全な通信とデータ保管の土台です。Webサイトの閲覧、メッセージアプリ、オンラインバンキング、パスワードの保存、ソフトウェアの真正性確認まで、見えないところで暗号技術が働いています。この土台を曖昧なまま使っていると、「暗号化したから安全」という思い込みで肝心の弱点を見落とすことになりかねません。

この記事では、暗号の四本柱とも言える「共通鍵暗号」「公開鍵暗号」「ハッシュ関数」「TLS」を取り上げ、それぞれが何のためにあり、どう組み合わさって情報を守っているのかを、原理から噛み砕いて説明します。NISTやIPAといった公的機関が示す一次情報をもとに、用語の定義も正確に押さえます。難しい数式は使いません。仕組みの「なぜ」が分かれば、暗号にまつわるよくある誤解も自然に解けていきます。

まず、これから登場する四つの技術が「情報セキュリティの三要素」のうち何を守るのかを早見表で整理します。全体像を先に掴むと、個々の説明が頭に入りやすくなります。

技術主な役割機密性完全性真正性(なりすまし防止)
共通鍵暗号(AES等)データの暗号化守る単体では守らない単体では守らない
公開鍵暗号(RSA・楕円曲線等)鍵の配送・デジタル署名守る署名と組み合わせて守る署名と組み合わせて守る
ハッシュ関数(SHA-2等)データの要約・改ざん検知守らない守る単体では守らない
TLS(HTTPSの中身)通信全体の保護守る守る守る(証明書による)

共通鍵暗号。一つの鍵で速く守る

共通鍵暗号は、暗号化する人と復号する人が「同じ鍵」を使う方式です。鍵を一つ共有していれば、その鍵でデータをスクランブルし(暗号化)、同じ鍵で元に戻せます(復号)。仕組みが素直で、計算も速いのが特長です。大きなファイルや通信データのように、量の多いデータをまとめて暗号化する用途には、この高速性が効いてきます。

現在の事実上の標準が AES(Advanced Encryption Standard)です。米国の標準化機関NISTが連邦標準FIPS 197として定めたもので、鍵の長さに128ビット・192ビット・256ビットの三種類があります。データは128ビット単位のブロックに区切って処理し、鍵長に応じて内部の変換処理(ラウンド)を10回・12回・14回繰り返す構造になっています。

NISTのFIPS 197はAESの仕様を定める連邦標準です。鍵長は128/192/256ビットの三種類で、いずれも安全と位置づけられています。総当たりに対する鍵空間は192ビット・256ビットのほうが大きく、計算能力の向上や解読技術の進歩に備えた選択肢になり得ます。ただし三種類とも承認済みであり、選定は性能や鍵管理を含めて判断するのが実務的です(執筆時点で参照した版の記載)。

共通鍵暗号の弱点は、名前のとおり「鍵をどう共有するか」にあります。離れた相手と安全に通信したいのに、その前提となる鍵そのものを安全に渡す手段がない、というジレンマが生じます。鍵を盗み見られれば、暗号文も読まれてしまうからです。この「鍵配送問題」を解決するのが、次の公開鍵暗号です。

注意

共通鍵暗号で暗号化しただけでは、データが「読まれない」ことは守れても、「改ざんされていない」ことや「送り主が本物である」ことは保証されません。暗号文を途中で書き換えられても、受け取った側はそれに気づけない場合があります。機密性と完全性・真正性は別の問題であり、別の仕組み(後述のハッシュや署名、あるいは認証付き暗号)で補う必要があります。

公開鍵暗号。二つの鍵で鍵配送と署名を解く

公開鍵暗号は、1970年代に考え出された画期的な方式です。暗号化に使う鍵と復号に使う鍵が「別々」になっているのが最大の特徴で、しかも一方の鍵を公開しても、もう一方の鍵は現実的に計算できないように作られています。この対になった鍵を「公開鍵」と「秘密鍵」と呼びます。公開鍵は誰に見せてもよく、秘密鍵は本人だけが厳重に持ちます。

代表的なアルゴリズムにRSAと楕円曲線暗号(ECC)があります。RSAは巨大な数の素因数分解の難しさに、楕円曲線暗号は楕円曲線上の離散対数問題の難しさに、それぞれ安全性の根拠を置いています。実用面では、楕円曲線暗号のほうが短い鍵長で同等の強度を得られるため、近年は採用が広がっています。NISTのガイドラインでは、RSAは鍵(モジュラス)が2048ビット未満のものは使用不可とされ、2048ビット以上が容認されています。

公開鍵暗号には二つの大きな使い道があります。一つは「鍵配送」です。相手の公開鍵で暗号化したデータは、対応する秘密鍵を持つ本人しか復号できません。これを使えば、事前に共通の鍵を渡しておかなくても、安全に秘密のデータ(たとえば共通鍵そのもの)を相手に届けられます。もう一つは「デジタル署名」で、これは後のセクションで詳しく扱います。

IPAの暗号技術Q&Aでは、共通鍵暗号は暗号化と復号に同じ鍵を使い高速である一方、公開鍵暗号は暗号化と復号で異なる鍵を使い、処理が共通鍵暗号より遅いという特徴が整理されています。両者を組み合わせて使う考え方も示されています。

弱点は速度です。公開鍵暗号は数学的に重い計算を伴うため、共通鍵暗号に比べて処理が遅くなります。大量のデータを公開鍵暗号だけで暗号化するのは現実的ではありません。そこで登場するのが、両者のいいとこ取りをするハイブリッド方式です。

ハイブリッド方式。速さと安全な鍵配送を両立する

実際の通信では、共通鍵暗号と公開鍵暗号を組み合わせる「ハイブリッド方式」が基本です。考え方はシンプルで、次のように役割を分けます。

まず、その場限りの共通鍵(セッション鍵)をランダムに生成します。実際のデータ本体は、この共通鍵を使ってAESなどで高速に暗号化します。そして、その共通鍵自体を相手の公開鍵で暗号化して届ける、あるいは後述の鍵交換手順で双方が同じ共通鍵を安全に共有します。こうすれば、鍵配送問題は公開鍵暗号(または鍵交換)で解きつつ、重いデータ処理は速い共通鍵暗号に任せられます。後で説明するTLSも、本質的にはこのハイブリッドの考え方で動いています。

で扱うVPNも、同様に鍵交換とデータ暗号化を組み合わせて通信を守っています。

ハッシュ関数。暗号化ではない「一方向の要約」

ここで多くの人がつまずく重要な区別をします。ハッシュ関数は「暗号化」ではありません。暗号化は鍵があれば元に戻せる(復号できる)処理ですが、ハッシュは元に戻せない一方向の処理です。任意の長さのデータを入力すると、決まった長さの短い値(ハッシュ値、ダイジェスト)を出力します。同じ入力からは必ず同じ出力が得られますが、出力から入力を逆算することは現実的にできません。

代表的なものにSHA-2系(SHA-256など)があります。NISTのガイドラインでは、SHA-256・SHA-384・SHA-512などのSHA-2系や、SHA-3系のハッシュ関数が各種用途に容認されています。一方、かつて広く使われたSHA-1は、デジタル署名の検証など一部の互換用途を除き、現在は使用しないこととされています。

ハッシュの良い性質は二つあります。第一に、入力が少しでも変われば出力が大きく変わること。第二に、同じハッシュ値になる別の入力を見つけるのが極めて困難であること(衝突困難性)。この性質のおかげで、ファイルやメッセージが途中で改ざんされていないか(完全性)を、ハッシュ値の照合で検知できます。配布ファイルに添えられた「チェックサム」や「SHA-256ハッシュ」は、まさにこの用途です。ただし、これが成り立つのは「信頼できる経路で入手した正しいハッシュ値」と照合する場合に限られます。攻撃者がデータとハッシュ値の両方を差し替えられる状況では、ハッシュ単体では改ざんを見抜けません。そうした場面では、鍵を使うHMACやMAC、あるいは後述のデジタル署名が必要になります。

メモ

ハッシュは「機密性」を守る道具ではありません。ハッシュ値を公開しても元データは復元されませんが、それは「秘密を守っている」のではなく「そもそも復元できない要約」だからです。秘密にしておきたいデータを隠す目的にはハッシュではなく暗号化を使います。役割がまったく違う点に注意してください。

パスワード保存。ソルトとストレッチング

ハッシュの代表的な実務用途が、パスワードの保存です。サービスがパスワードを平文(そのままの文字列)で保存していると、データベースが漏えいした瞬間に全利用者のパスワードが筋抜けになります。そこで、パスワードはハッシュ化して保存し、ログイン時には入力値をハッシュ化して保存値と照合します。元に戻せないからこそ、漏えい時の被害を抑えられます。

ただし、ただハッシュ化するだけでは不十分です。二つの工夫が要ります。一つは「ソルト」です。利用者ごとに異なるランダムな文字列をパスワードに付け足してからハッシュ化します。これにより、同じパスワードでもハッシュ値が利用者ごとに変わり、あらかじめ計算した変換表(レインボーテーブル)による一括解読を防げます。もう一つは「ストレッチング」で、ハッシュ計算をわざと何度も繰り返して時間をかけ、総当たり攻撃の効率を下げます。

OWASPの指針では、パスワード保存にはArgon2id・scrypt・bcrypt・PBKDF2といった、意図的に遅く設計された専用のハッシュ方式を使うことが推奨されています。第一選択はArgon2idで、メモリと反復回数のパラメータを十分に設定します。広く使われているライブラリの多くはソルトの生成と保存を内部で自動的に行うため、正しく使えば開発者が手作業でソルトを付ける必要は通常ありません。ただし低レベルなAPIではソルトの指定が必要な場合もあるので、利用するライブラリが推奨する保存形式に従ってください。逆に言えば、SHA-256のような汎用ハッシュを素のままパスワード保存に使うのは、計算が速すぎて総当たりに弱く、推奨されません。

OWASPのPassword Storage Cheat Sheetは、パスワード保存に強くて遅いハッシュ(Argon2id・scrypt・bcrypt・PBKDF2)を使うこと、利用者ごとに一意のソルトを付けることを推奨しています。第一選択はArgon2idで、最低でもメモリ19MiB・反復2回・並列度1の設定が挙げられています(執筆時点の記載)。

利用者側の対策としては、結局のところサービスごとに長く別々のパスワードを使うことが効きます。詳しくは

を参照してください。

デジタル署名と証明書。なりすましを防ぐ

ここまでで、暗号化は「読まれないこと(機密性)」を、ハッシュは「改ざんされていないこと(完全性)」を守ることが分かりました。しかし、もう一つ重要な問いが残っています。「そのデータを送ってきた相手は、本当に本人なのか」。これを保証するのがデジタル署名です。

デジタル署名は、公開鍵暗号とハッシュを組み合わせて作ります。送信者は、まず送るデータのハッシュ値を計算し、それを自分の「秘密鍵」で処理して署名を作ります。受信者は、送信者の「公開鍵」でその署名を検証し、自分でも同じデータのハッシュ値を計算して一致するか確かめます。一致すれば、(1)データが改ざんされていない(完全性)、(2)署名は対応する秘密鍵の持ち主が作った(真正性)、の二つが同時に確認できます。秘密鍵は本人しか持たないため、なりすましを防げるわけです。

ここで新たな疑問が湧きます。「検証に使う公開鍵が、本当にその相手のものだと、どうやって信じればよいのか」。攻撃者が偽の公開鍵を本人のものだと偽れば、署名の仕組みごと欺かれてしまいます。これを解決するのが「デジタル証明書」と、それを発行する「認証局(CA)」です。証明書は、ある公開鍵が確かに特定の相手(たとえば特定のWebサイト)のものであることを、信頼された認証局がデジタル署名によって裏書きした電子的な身分証明書です。

「公開鍵を信じるために、また別の鍵が要るなら、結局どこかで信じる起点が要るのでは」と感じるのは正しい直感です。実際、信頼は連鎖でつながっており、その出発点が「ルート認証局」です。OSやブラウザには、信頼できるとあらかじめ判断されたルート認証局の証明書が組み込まれています。この組み込みの信頼を土台に、証明書の連鎖をたどって個々のサイトの公開鍵の正しさを確かめる、という仕組みになっています。

入門者がよく抱く疑問

TLS。HTTPSで実際に何を守っているのか

最後に、これまでの要素が一つに統合された姿がTLS(Transport Layer Security)です。WebサイトのURLが「https://」で始まり、ブラウザに鍵マークが出ているとき、その通信はTLSで保護されています。HTTPSとは、要するにHTTP通信をTLSで包んだものです。

TLSは通信の最初に「ハンドシェイク」と呼ばれる手順を行います。ここで次のことが起こります。サーバは自分の証明書を提示し、ブラウザはその証明書を検証して相手が本物のサーバであることを確認します(真正性)。続いて、公開鍵暗号や鍵交換の仕組みを使って、双方だけが知る共通鍵(セッション鍵)を安全に共有します(鍵配送問題の解決)。以降の実データのやり取りは、この共通鍵を使って高速に暗号化されます(機密性)。さらに、各メッセージには改ざん検知の仕組みが付き(完全性)、途中で書き換えられればすぐに分かります。

つまりTLSは、共通鍵暗号・公開鍵暗号・ハッシュ・証明書のすべてを組み合わせ、機密性・完全性・真正性の三つをまとめて守るプロトコルなのです。現在の最新版はTLS 1.3で、古くて弱い暗号方式を排除し、ハンドシェイクを高速化しています。通常の(EC)DHE鍵交換を用いるハンドシェイクでは、過去の通信が後から解読されにくくなる前方秘匿性を標準で備えています(事前共有鍵を単独で使う構成や0-RTTの早期データには、前方秘匿性の例外がある点には注意が必要です)。

IPAは「TLS暗号設定ガイドライン」などを公開し、安全なTLSの設定方針を整理しています。サーバ運用者は、推奨される暗号方式やプロトコルバージョンを選び、古く弱い設定を避けることが求められます。

ここで実務上の大事な注意点があります。鍵マークが出ていることが意味するのは「あなたとそのサーバの間の通信が暗号化され、サーバの身元が証明書で確認できた」ことだけです。「そのサイトが善意のサイトである」ことや「中身が安全である」ことまでは保証しません。フィッシングサイトでも正しい証明書を取得してHTTPS化できるため、鍵マークだけを安全の証と考えるのは危険です。守られているのは通信路であって、相手の善悪ではない、という線引きが重要です。

よくある誤解を解く

暗号にまつわる誤解は、実務での事故につながりやすいものです。代表的なものを正面から扱います。

第一に、「暗号化」と「難読化(エンコード)」の混同です。Base64のようなエンコードは、データの表現形式を変えているだけで、鍵を必要としません。誰でも元に戻せるため、秘密を守る機能はまったくありません。「Base64で隠した」つもりは、隠せていないのです。暗号化と呼べるのは、鍵を知らなければ元に戻せない処理だけです。

第二に、「暗号化」と「ハッシュ」の混同です。前述のとおり、暗号化は鍵で元に戻せる双方向の処理、ハッシュは元に戻せない一方向の処理です。「パスワードを暗号化して保存している」と説明するサービスが、本来はハッシュ化すべき場面で可逆な暗号化をしているなら、鍵が漏れた際に全パスワードが復元される危険があります。用途に応じた使い分けが要ります。

第三に、最も重大な「独自暗号(自家製暗号)」の危険です。「秘密のアルゴリズムなら誰にも破られない」という発想は、暗号の世界では逆効果とされています。安全な暗号は、アルゴリズムを公開しても鍵さえ秘密なら破られない、という性質(ケルクホフスの原理)を満たすべきものです。AESのような標準アルゴリズムは、世界中の専門家による長年の検証を経て安全性が確かめられています。検証を受けていない独自方式は、思わぬ弱点を抱えていることがほとんどで、自前で暗号を発明しないことが鉄則です。

注意

強いアルゴリズムを使っていても、鍵の管理がずさんなら全体が破綻します。鍵をソースコードに直書きする、暗号化したデータと同じ場所に鍵を保管する、複数システムで同じ鍵を使い回す、といった運用は、AES-256を使っていても安全とは言えません。暗号の安全性は最終的に「鍵をいかに守るか」に帰着します。鍵管理こそが暗号運用の心臓部だと考えてください。

実務で守るべき判断基準を、最後に整理しておきます。秘密を守りたいなら暗号化、改ざん検知やパスワード保存ならハッシュ(パスワードは専用の遅いハッシュ)、相手の真正性まで守りたいなら署名と証明書。そして通信全体はTLSに任せ、自前で暗号を組み立てない。この対応づけを押さえておけば、大きな間違いは避けられます。なお、暗号は認証(本人確認)を置き換えるものではありません。通信や保存を暗号で守ったうえで、ログインには多要素認証を重ねることが現実的な守りになります。認証の強化については

を参照してください。

よくある質問

結局、共通鍵暗号と公開鍵暗号はどちらが優れているのですか?
優劣ではなく役割分担です。共通鍵暗号は高速なので大量のデータ暗号化に向き、公開鍵暗号は鍵配送と署名に強みがあります。実際の通信は両者を組み合わせたハイブリッド方式で動いており、TLSもこの形をとっています。どちらか一方だけでは現実的な安全な通信は成り立ちません。
ハッシュ化と暗号化は何が違うのですか?
暗号化は鍵があれば元のデータに戻せる双方向の処理で、機密性を守ります。ハッシュは元に戻せない一方向の要約で、改ざん検知やパスワード保存に使い、完全性の確認に向きます。秘密を守るのが暗号化、改ざんを検知するのがハッシュ、と役割が異なります。
鍵マークが出ていれば、そのサイトは安全と考えてよいですか?
いいえ。鍵マークは『通信が暗号化され、サーバの身元が証明書で確認できた』ことを示すだけです。サイトの中身が善意か、安全かまでは保証しません。フィッシングサイトもHTTPS化できるため、鍵マークだけを安全の根拠にせず、URLや運営元も確認してください。
AES-256とAES-128では、256のほうを必ず選ぶべきですか?
用途次第です。NISTはいずれも安全と位置づけており、128ビットでも現実的には十分強いとされています。256ビットは将来の計算能力向上や解読技術の進歩に備えた選択肢になり得ますが、その分処理は重くなります。鍵長より、鍵管理や実装の正しさのほうが事故の原因になりやすい点に注意してください。
自社サービスで独自の暗号方式を作るのは良くないのですか?
推奨されません。安全な暗号は、アルゴリズムを公開しても鍵が秘密なら破られない性質を満たすべきもので、それは長年の専門家による検証で確かめられます。検証を受けていない独自方式は思わぬ弱点を抱えがちです。AESなどの標準アルゴリズムを正しく使うのが鉄則です。

まとめ

暗号の基礎を押さえるチェックリスト

  • 共通鍵暗号(高速・鍵配送が課題)と公開鍵暗号(鍵配送・署名に強い)の役割の違いを説明できる
  • 実際の通信はハイブリッド方式で動くことを理解した
  • ハッシュは暗号化ではなく、元に戻せない一方向の要約だと区別できる
  • パスワード保存にはソルト付きの専用の遅いハッシュ(Argon2id等)を使うべきと理解した
  • デジタル署名と証明書がなりすまし防止(真正性)を担うことを把握した
  • TLSが機密性・完全性・真正性をまとめて守り、鍵マークは通信路の保護を意味すると理解した
  • 暗号化と難読化・ハッシュの違い、独自暗号の危険、鍵管理の重要性を区別して説明できる

暗号は、それ単体で「安全」を与えてくれる魔法ではありません。共通鍵暗号は機密性を、ハッシュは完全性を、署名と証明書は真正性を、それぞれ別の角度から守り、TLSがそれらを束ねて通信を保護します。どの技術が何を守り、何を守らないのかという線引きを押さえることが、暗号を正しく使う第一歩です。そして、どれだけ強いアルゴリズムを選んでも、最後は鍵管理に行き着きます。標準のアルゴリズムを正しく使い、鍵を厳重に守る。この基本を踏まえたうえで、認証の強化として

もあわせて読み進めることをおすすめします。

出典・参考

この記事をシェア

関連する記事