エンジニア視点でまとめる認証・暗号関連キーワード
はじめに
こんにちは、バックエンドエンジニアのデニスです。普段はGoでSaaSを作っています。
私は認証や暗号の専門家ではありませんが、セキュリティ関連のテーマには長い間興味を持っていて、新サービスの認証まわりやデータ漏洩などのインシデントに関するニュース記事のコメント欄やオンライン掲示板をよくチェックしています。
そうしたコメントを読んでいると、時々「この人が言っていること間違ってない?」と思う一方で、「もしかしたら自分の方が間違っているかも?」と不安になることがあります。
改めて自分で調べてみると、ニュース記事のコメント欄やオンライン掲示板で意見を述べる人たちや私を含めたエンジニアの前提知識にかなりのばらつきが生じているように見えて、セキュリティや暗号の専門家が発信する情報と、実装者であるエンジニアの知識レベルに大きな乖離があるのではないか?と思うようになりました。
そこで、自分自身を含めたエンジニアのセキュリティ知識を底上げする一助になればと思い、エンジニアの立場から、このテーマについてわかりやすくまとめてみました。なお、用語の意味だけでなく例も挙げることで、より具体的に想像できるように意識しました。また、体系的なコンテクストや関連性も含めてまとめてみました。
よく聞く用語はもちろん、あまり聞いたことのないコンセプトも少し交えてみましたので、新しい発見が一つでもあれば幸いです。
認証
二要素認証 (Two-factor authentication, 2FA)
一般的に「多要素認証 (Multi-factor authentication, MFA)」とも呼ばれます。
要素
認証に用いられる「要素」には、以下の3つのカテゴリーが存在します。
-
知識(Something you know)
ユーザー本人しか知り得ない情報を指します。
最も一般的なのはパスワードですが、他に暗証番号や合言葉などがあります。 -
所持(Something you have)
ユーザーが所有している物理的なものを指します。
アナログな例では鍵や印鑑が該当します。インターネットサービスにおいては、ほとんどの場合スマートフォンやYubiKeyのような認証デバイスを指します。 -
生体(Something you are)
ユーザーの生物学的特性を指します。
広く使われているのは指紋、顔、虹彩などです。
「二要素認証」は文字通り、上記の異なるカテゴリーに属する2つの要素を組み合わせてユーザーを認証する方法です。例えば、パスワード(知識)とスマートフォンによる認証(所持)の組み合わせが最も一般的です。
二段階認証 (Two-step verification, 2SV)
二要素認証とは異なり、二段階認証は「要素」の種類を限定しない認証方法です。例えば、パスワード(知識)と秘密の質問(知識)のように、同じカテゴリーの要素を2段階で用いることも許容されます。
厳密に言えば、すべての二要素認証は二段階認証に含まれます。しかし、先ほどのパスワードと秘密の質問の組み合わせは、「一要素二段階認証」と表現できます。
否定可能認証 (Deniable Authentication)
否定可能認証には、以下の2つの特徴があります。
- AliceがBobにメッセージを送った際、Bobはそのメッセージの送信者がAliceであることを確認できる。
- Bobは、Aliceが送った内容が本当にAliceによって書かれたものであることを、誰に対しても証明できない。
否定可能認証の要点は、AliceとBobが同じ秘密鍵を共有している点にあります。この秘密鍵は両者しか知らないため、第三者がメッセージを偽造することはできません。しかし、同じ鍵を持っているのはAliceとBobのみであるが故に、BobはAliceの発言が本物であることを第三者に証明できず、AliceもBobの発言を証明できません。なぜなら、自分自身が書いたメッセージである可能性を否定できないからです。
セキュリティ
情報セキュリティ (Information Security, InfoSec)
情報セキュリティとは、情報の機密性(Confidentiality)、完全性(Integrity)、**可用性(Availability)**を維持することを指します。主に情報を保護するためのルールや仕組みを意識することが中心となります。具体的な例としては、プロダクトのリリース日が漏洩しないよう常にコードネームを使用することや、パソコンから離れる際は必ずロックをかけるなど、習慣化を目的としたルールが挙げられます。
オペレーショナルセキュリティ (Operation Security, OPSEC)
オペレーショナルセキュリティは、主にリスクを洗い出し、それに対する対策を講じることを指します。InfoSecがルールを守ることに重点を置くのに対し、OPSECは、あるプロセスや計画を外部の視点から分析し、潜在的な攻撃経路(アタックベクター)を特定・排除することを目的とします。サイバー空間だけでなく、現実世界におけるアプローチがより顕著です。
例えば、旅行中のOPSECを考える場合、家が空になる状況を想定します。ここで「攻撃者」の視点から自宅を眺め、あらゆるシナリオとそのリスクを分析します。
- 誰から家を守りたいのか?おそらく空き巣でしょう。ここでロシアのスパイを想定して、より多くのリソースを費やす必要はありませんよね。
- 隣人は脅威になるか?
- 信用できない家族がいるのか?
対策も同様に考えます。防犯カメラの設置(物理的セキュリティ)、テレビをつけっぱなしにする(戦略的欺瞞)、誰かに家をチェックしてもらう(物理的セキュリティ、人的セキュリティ)など、対策は多岐にわたります。リスクと対策、そしてその妥当性を検討することこそがOPSECなのです。
暗号
暗号技術は、非常に優れた頭脳を持つ専門家たちが研究・開発して生まれたものです。しかし、開発者(暗号の利用を想定するエンドユーザー)向けのドキュメントは専門性が高く、前提知識が求められることが多いでしょう。そのため、ここではいくつかの重要な暗号用語について簡単に説明します。
ポスト量子暗号 (Post-quantum Cryptography, PQC)
ポスト量子暗号とは、量子コンピュータが実用化されても安全性を維持できる暗号を指します。現在広く使われている(公開鍵)暗号のほとんどは、整数因数分解問題、離散対数問題、楕円曲線離散対数問題という3つの数学的難問のいずれかにその安全性の根拠を置いています。しかし、現時点では難問と言われているこれら3つの問題でさえ、十分に強力な量子コンピュータであれば容易に解読されてしまう可能性があります。
ポスト量子暗号とは、量子コンピュータでも既存のコンピュータでも解くことが難しいとされる新たな数学的問題に基づいて設計された暗号のことです。
否定可能暗号 (Deniable Encryption)
否定可能暗号とは、平文データの存在自体を否定できる暗号です。復号時に使用する鍵(パスワードなど)によって、復号される内容が異なるという特徴があります。
これを実現するために、正規の秘密鍵と「犠牲となる鍵」を使用し、本物のメッセージと偽のメッセージの両方を暗号化します。もしパスワードを要求された際(例えば、強制的な尋問など)に犠牲の鍵を教えれば、復号されるのは偽のメッセージのみとなります。これにより、本物のメッセージや秘密鍵の存在を誰にも悟らせないことが可能になります。
準同型暗号 (Homomorphic Encryption)
準同型暗号とは、暗号化されたデータを復号することなく、そのまま演算処理を行うことができる暗号です。これにより、データが平文で処理される必要がなくなるため、処理中のデータに対する攻撃者からのアクセスを防ぐことができます。
RSA暗号など、整数論をベースとした多くの公開鍵暗号は準同型性の一部を備えています。
フォーマット保持暗号 (Format-preserving Encryption, FPE)
フォーマット保持暗号とは、データを保護しつつ、暗号化後のデータが元の形式を維持する暗号です。例えば、16桁のクレジットカード番号を暗号化しても、出力されるのは引き続き16桁の数字となります。
これは、既存システムのデータ設計における課題を解決します。例えば、クレジットカードを扱うシステムでは、クレジットカード番号を格納するために特定のデータ型やデータベースカラムのサイズが定義されています。一般的な暗号化ではランダムなバイト列が出力されるため、システムの設計を大幅に変更する必要性が生じます。フォーマット保持暗号を使用すれば、既存の設計を変更することなく安全性を確保することができます。
検索可能暗号 (Searchable Encryption)
検索可能暗号とは、暗号化されたデータに対しても検索を行うことが可能な暗号です。信頼できないストレージにファイルをアウトソーシングする際に、ファイルが平文で公開されることなく、検索機能を利用できる方法を提供します。
検索可能暗号は基本的に共通鍵暗号の仕組みに基づいています。鍵と検索キーワードから「検索トークン」を生成し、そのトークンを使って暗号化されたデータを検索するという仕組みです。
その他のキーワード
前方秘匿性 (Forward Secrecy, FS)
前方秘匿性とは、セッション鍵の交換に使用される長期的な秘密鍵が万一侵害された場合でも、個々のセッション鍵は侵害されず、その被害を限定的なものにできるという鍵交換プロトコルの性質です。
以下の例で考えてみましょう。
- 長期鍵の生成と検証: AliceとBobはそれぞれ長期的な非対称公開鍵と秘密鍵のペアを生成し、公開鍵のフィンガープリントを直接会うか、すでに認証済みのチャネルを介して検証します。この検証により、ある公開鍵を所持していると主張した者が実際にその所有者であることを証明することができます。
- 一時的なセッション鍵の生成: AliceとBobは、Diffie-Hellmanのような鍵交換アルゴリズムを使用して、一時的なセッション鍵を安全に生成することができます。ステップ1で生成した長期鍵は、このプロセス中にお互いを認証するためだけに使用されます。
- メッセージの暗号化: AliceとBobは、メッセージを送信する際、ステップ2で生成したセッション鍵を使って対称暗号でメッセージを暗号化します。
- メッセージの復号: Bobはステップ2で生成したセッション鍵を使ってAliceのメッセージを復号します。
- プロセスの繰り返し: 新しいメッセージを送信する毎に、ステップ2からのプロセスを繰り返します(送信者と受信者の役割は適宜入れ替わります)。ステップ1の長期鍵の生成と検証は二度と繰り返されません。
このように、ステップ2の繰り返しによって生成されたセッション鍵のいずれかが漏洩したとしても、その鍵は単一のメッセージの暗号化にのみ使用されるため、過去や未来の通信が復号できないことが保証されます。
ゼロ知識証明 (Zero Knowledge Proof, ZKP)
ゼロ知識証明とは、ある当事者(証明者)が別の当事者(検証者)に対し、ある記述が真実であることを、その記述が真実であるという事実以外のいかなる情報も検証者に伝えることなく納得させることができるプロトコルです。
数学を使用しない例として、AliceがBobに対して、52枚の標準的なトランプの山札から赤いカードを引いたことを、具体的にどの赤いカードであるかを明かさずに証明したい場合を考えます。BobはAliceがシャッフルされた山札からランダムにカードを引くのを目撃しますが、Aliceはカードを裏向きにしたままなので、Bobはそれを見ることができません。
自分のカードが赤いことを実際にカードを見せずに証明するため、Aliceは山札の残り51枚のカードを取り、スペード13枚とクラブ13枚の合計26枚の黒いカードを1枚ずつ、表向きにしてテーブルに並べてBobに見せます。標準的なトランプには赤いカードが26枚、黒いカードが26枚ちょうど含まれています。Aliceがすべての黒いカードが山札に残っていることを示したので、BobはAliceが隠し持っているカードが赤であると納得することができます。
この証明はゼロ知識です。なぜなら、BobはAliceのカードが赤いことしか知らず、それがハートなのかダイヤなのか、あるいは具体的にどの数字の赤いカードを持っているのかについての情報は一切得られないからです。この証明は、Aliceがハートのエースを持っていてもダイヤの2を持っていても、同様に説得力があります。さらに、もしこのやり取りが記録されたとしても、その記録は将来の観察者にAliceの具体的なカードを明かすことはなく、ゼロ知識性が保たれます。
もしAliceが嘘をついていて、実際には黒いカードを持っていた場合、残りの山札から26枚すべての黒いカードを出すことはできないため、欺瞞は不可能となります。これは、この証明システムの健全性を示します。
攻撃
中間者攻撃 (Man-in-the-middle attack, MITM attack)
中間者攻撃とは、攻撃者が密かに通信を中継し、場合によっては内容を改ざんするサイバー攻撃です。この攻撃では、通信する2つの当事者は直接通信していると思っていますが、実際には攻撃者がその間に割り込んでいます。
中間者攻撃は、認証と改ざん検知という2つの方法で防止または検知できます。認証は、特定のメッセージが正当な送信元から来たという確実性をある程度提供します。一方、改ざん検知は、メッセージが改ざんされた可能性があり、その完全性が損なわれているという証拠を示すにすぎません。
コミュニケーションの間に割り込む方法は多岐にわたりますが、最も一般的なパターンは、HTTPS接続をHTTPにダウングレードさせたり、偽のSSL/TLS証明書を使用したり、そして偽のWi-Fiホットスポットを設定したりすることです。
サイドチャネル攻撃 (Side-channel attack)
サイドチャネル攻撃とは、プロトコルやアルゴリズム自体の設計上の欠陥(例えば、暗号アルゴリズムの暗号解読で見つかる欠陥)や、実装における致命的なミスや見落としではなく、コンピュータのプロトコルやアルゴリズムが実装されている「物理的な方法」によって収集できる追加情報に基づいて行われるあらゆる攻撃のことです。
代表的な方法として「タイミング攻撃」があります。タイミング攻撃では、攻撃者が認証などの処理にかかるごくわずかな時間の差分を測定し、そのデータをもとにリクエストデータを調整して認証を突破します。
通常はハッシュを比較しますが簡単な例として ==
を使ったパスワードの文字列比較でタイミング攻撃を考えましょう。文字列の比較は、先頭から1文字ずつ比較し、一致しない文字が見つかった時点で不一致と判断します。最後まで不一致となる文字がなければ、両方の文字列が一致していると判断します。つまり、最初の文字が一致しない場合と、最後の文字まで比較して一致しない場合とでは、処理時間が異なります。この情報(サイドチャネル)を利用して、パスワードを推測することができます。例えば、「a」を試した際のレスポンス時間が、「b」を試した際のレスポンス時間よりも長かった場合、パスワードが「a」から始まっている可能性が高いと判断できるわけです。なお、パスワードのハッシュを ==
で比較した場合もタイミング攻撃が可能であるため、処理時間を一定化する必要があります。
他にも、キーボードの打鍵音から入力内容を推測する攻撃や、電力消費をモニタリングする攻撃などがあります。攻撃者の工夫次第で多様な方法が考えられます。
締め上げ暗号分析 (Rubber-hose cryptanalysis)
締め上げ暗号分析とは、暗号化された秘密(例えば、暗号化されたファイルのパスワードなど)を、「ゴムホースで殴る」といった拷問や強制によって人から引き出すことを婉曲的に表現した言葉です。
極端な言葉ではありますが、これは警察の尋問でパスワードを求められることや、金銭による買収(お金を使って情報を引き出す)なども含まれることがあります。
締め上げ暗号分析の対策として、否定可能暗号が有効とされます。
最後に
今回はよく耳にする用語や、あまり知られていないものの有益なコンセプトについて解説しました。もっと詳しく知りたいと思った内容や他にも気になるテーマがあったらぜひコメントで教えて下さい!
この記事が、セキュリティを意識した実装や致命的ミスの予防に少しでもつながればうれしいです。
Discussion