0Pricing
Cryptology Academy · レッスン

アプリケーションレベルのコードに対するタイミング攻撃

文字列比較の時間差から秘密情報が漏洩する仕組みと、constant-time比較による防止方法を学びます。

「アプリケーションレベルのコードに対するタイミング攻撃」はCoddyKit上の無料Cryptology Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはCryptology Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Cryptology Academyコースには全4レッスンが含まれています。

一定時間でない文字列比較

ほとんどのプログラミング言語における標準の文字列等価演算子は、不一致が見つかるとすぐに処理を終了します。Python の bytes オブジェクトに対する ==、C の strcmp、Java の String.equals は、最初に異なるバイトが見つかると直ちに戻ります。通常の文字列比較ではこれは最適化ですが、MAC タグやパスワードなどの秘密値を比較する場合は、測定可能なタイミングサイドチャネルを生み出し、情報を漏洩させます。

HMAC 比較時間の測定

攻撃者は、送信されたHMACタグと正しい値を比較するのにかかる時間を測定します。最初のバイトが正しく一致するHMACを送信すると、最初のバイトが間違っているものよりわずかに長い時間がかかります(比較するバイトが1つ多くなるためです)。各可能な先頭バイトを含む値を多数送信して応答時間を測定することで、攻撃者は正しい最初のバイトを特定します。この処理をバイトごとに繰り返すと、最終的にタグ全体を復元できます。

実用的な攻撃に必要なタイミング精度

現代のネットワークタイミング攻撃では、インターネット経由でも数十〜数百ナノ秒の時間差を検出できます。32バイトのHMAC比較で、正しいバイト1つにつき約10-100nsの処理時間が加わる場合、十分な回数の測定を行ってネットワークジッターを平均化すれば、測定可能なシグナルが得られます。ローカルネットワーク環境では、十分な統計的サンプリングにより、1ナノ秒単位の差さえ悪用できます。

Pythonの==演算子の脆弱性

Pythonでは、MACタグの比較に==を使うのは安全ではありません。mac == submitted_macは、最初の不一致がどの位置にあるかによってTrueまたはFalseを返すまでの時間が変わります。攻撃者は細工したタグを数千回送信して応答時間を測定することで、期待されるタグをバイトごとに復元できます。この脆弱性は、constant-time関数を使わずにセッショントークンやAPIキーの比較を実装した本番Webアプリケーションでも発生しています。

Pythonのhmac.compare_digest

Pythonのhmac.compare_digest(a, b)は、2つのバイト列または文字列をconstant-timeで比較します。最初の不一致がどこにあるかにかかわらず、常に同じ時間がかかります。これはCで実装されているため、Pythonのバイトコード解釈によるオーバーヘッドがあってもconstant-timeの動作が保証されます。MACタグ、セッショントークン、APIキー、その他タイミング情報が危険につながる値を比較する場合は、必ずhmac.compare_digestを使用してください。

OpenSSLのCRYPTO_memcmp

OpenSSLは、constant-timeのメモリ比較を行うCRYPTO_memcmp(a, b, length)を提供しています。memcmpとは異なり、途中で不一致が見つかっても、常にlengthバイトをすべて処理します。戻り値は、一致する場合は0、異なる場合は0以外です。常に期待される長さ全体を比較することが重要です。異なる長さの値を短い方の長さで比較すると、長さの情報が漏れる可能性があります。OpenSSLを使用するC/C++コードでセキュリティ上重要な比較を行う場合は、CRYPTO_memcmpを使用してください。

RSAに対するタイミング攻撃:Bleichenbacher

タイミング攻撃は、文字列比較に限られません。Bleichenbacherが2006年に行ったRSA PKCS#1 v1.5復号への攻撃は、SSL/TLS実装に対する実用的なタイミングオラクルを実証しました。RSA秘密鍵操作にかかる時間は、復号された値が有効なPKCS#1パディングを持つかどうかによって変化しました。細工した暗号文を数千回送信することで、攻撃者はRSA秘密鍵を復元できました。これをきっかけに、RSA-OAEPとconstant-time RSA実装が採用されるようになりました。

AESに対するキャッシュタイミング攻撃

ルックアップテーブルを使用するAES実装(パフォーマンス向上のため一般的に使われます)では、鍵と平文に応じて異なるテーブルエントリにアクセスします。キャッシュヒットとキャッシュミスによって測定可能な時間差が生じ、どのテーブルエントリにアクセスしたかという情報が漏れます。このサイドチャネルによってAES鍵が明らかになる可能性があります。対策として、AES-NIハードウェア命令やビットスライス方式のソフトウェア実装など、テーブルルックアップに依存しないAES実装を使用します。

Constant-Time実装の原則

constant-timeコードを書くには、秘密データに基づく条件分岐(マスクを使ったブランチレス選択を使用します)、秘密データに依存するメモリアクセスパターン(秘密データをインデックスにするルックアップテーブルを避けます)、秘密の値によってレイテンシが変わる操作(プロセッサによっては除算など)を避ける必要があります。コンパイラはconstant-timeの構造を最適化で除去する可能性があるため、重要なセクションではアセンブリやvolatileメモリアクセスが必要になることがあります。

AEADによるアプリケーションレベルのMAC比較の排除

MAC比較に対するタイミング攻撃の最善の防御策は、AEADモード(GCM、ChaCha20-Poly1305)を使用し、MAC検証を暗号ライブラリに委譲することです。ライブラリの実装は、内部でconstant-time検証を行います。AEADを正しく使用している場合(改ざんがあると復号に失敗し、タグを検証する前に復号を決して行わない場合)、アプリケーションコードでMACタグを比較する必要はありません。そのため、タイミングの脆弱性を完全に排除できます。

タイミング脆弱性のテスト

タイミング脆弱性のテストには、応答時間分布の統計分析が必要です。tlsfuzzer、タイミング攻撃テストスクリプト、dudectフレームワークなどのツールは、暗号実装における時間差の検出に役立ちます。同じ時間になるはずの入力について応答時間のサンプルにt検定を行うと、統計的に有意な差を検出できる場合があります。偽陰性も起こり得るため、テストと併せてconstant-timeコードのレビューも不可欠です。

Constant-Time比較

タイミング攻撃を防ぐため、HMACタグを安全に比較するにはPythonのどの関数を使用すべきですか?

タイミング攻撃のまとめ

タイミング攻撃の要点は次のとおりです。早期終了する文字列比較では、応答時間の差を通じて秘密の値がバイトごとに漏れます。この差は、十分なサンプルがあればネットワーク越しでも測定できます。constant-time比較にはPythonではhmac.compare_digest、OpenSSLではCRYPTO_memcmpを使用してください。RSAパディングのタイミング攻撃によって秘密鍵が侵害される可能性があるため、constant-time RSAとOAEPを使用します。AESのテーブルルックアップに対するタイミング攻撃では鍵のビットが漏れるため、AES-NIまたはビットスライス方式の実装を使用します。AEADライブラリによる検証を使えば、アプリケーションレベルでMACタグを比較する必要がなくなります。

よくある質問

「アプリケーションレベルのコードに対するタイミング攻撃」レッスンは無料ですか?

はい。「アプリケーションレベルのコードに対するタイミング攻撃」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Cryptology Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Cryptology Academyコースには全4レッスンが含まれています。

「アプリケーションレベルのコードに対するタイミング攻撃」で何を学びますか?

文字列比較の時間差から秘密情報が漏洩する仕組みと、constant-time比較による防止方法を学びます。 ブラウザで直接実行するハンズオンコードでCryptology Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Cryptology Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのCryptology Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「アプリケーションレベルのコードに対するタイミング攻撃」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このCryptology Academyレッスンでコードを書いて実行できますか?

はい。すべてのCryptology Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Padding Oracle攻撃を詳しく学ぶ
  2. リプレイ攻撃とNonce再利用の脆弱性
  3. アプリケーションレベルのコードに対するタイミング攻撃
  4. 暗号の代表的な誤用パターン
← Cryptology Academyに戻る