_man 3 memcmp
_から:
必要なCPU時間は等しいバイト数に依存するため、
memcmp()
を使用して暗号シークレットなどのセキュリティの重要なデータを比較しないでください。代わりに、一定の時間で比較を実行する関数が必要です。
どうしてこんなことに?私の考えでは、誰かがこの「セキュリティクリティカルなデータ」を処理するマシンにアクセスできる場合、その人はRAMから抽出できるため、これらの秘密はすでに侵害されています。または、そのユーザーがマシンにアクセスできない場合、CPU時間を正確に測定できません。
タイミング情報の悪用は、パスワード認証システムなどに対する攻撃の可能性の1つです。
概念的にはmemcmp()
は、2バイトのバイナリデータをバイトごとに比較することで機能します(実際には、最適化によっては、プロセッサは一度に複数のバイトを比較できますが、以下の同じ原理が適用されます)。この関数は、データの先頭から始まり、各バイトを順番に比較して、違いが見つかるとすぐに終了します。違いが見つからない場合、関数はデータが一致することを示すコードを返します。
関数は違いを見つけるとすぐに戻るため、十分に正確なクロックを持つ攻撃者は秘密情報を推測できます。異なる入力でmemcmp()
への呼び出しを誘発し、どの入力に時間がかかるかを測定することで、格納されているシークレットを推測できます。
例:
従来のパスワードハッシュシステムを考えてみましょう。パスワードがシークレットハッシュとして保存されているとします。たとえば、Ek8fAMjPhBo
とします。 (そのハッシュは、na
のソルトとsecret
のパスワードを使用して、Linux crypt()
関数によって提供されるDESスキームを使用して生成されました。この関数はinsecureであり、実際のシステムでは使用しないでください。)
強力なパスワードシステムでは、ハッシュEk8fAMjPhBo
は保存されますが、パスワードは保存されません。システムの認証を求められると、システムはパスワードを取得してハッシュし、2つのハッシュを互いに比較します。結果のハッシュが一致する場合、システムへのアクセスが許可されます。ハッシュが一致しない場合、パスワードは拒否されます。これにより、実際にパスワード自体を保存することなく、システムがパスワードを知っているかどうかを確認できます。
攻撃者がタイミングを使用してこのシステムを攻撃する方法:
このシステムを攻撃するために、攻撃者は実際に保存されたハッシュにどのパスワードがハッシュされるかを理解する必要があります。通常、保存されたハッシュは秘密にされますが、攻撃者はタイミング情報を使用して、保存されたハッシュが何であるかを推測できます。敵対者が格納されたハッシュを推測すると、それははるかに高速でオフラインのレインボーテーブル攻撃に対して脆弱であり、パスワードの再試行制限などのオンラインのセキュリティ対策を回避します。
上記のパスワードシステムは、適切に機能するために、候補ハッシュを保存されているハッシュと比較する必要があります。候補ハッシュの各バイトを秘密に保存されたハッシュと比較するのに10ナノ秒かかると仮定します。一致するバイトがない場合(1つの比較)、memcmp()
は約10nsかかります。 1バイトが一致する場合(2つの比較)、memcmp()
は約20nsかかります。攻撃者はいくつかのパスワードを生成し、それらをシステムで実行して、各パスワードの所要時間を記録します。最初の数回のハッシュ比較にそれぞれ約10ナノ秒かかり、その後戻ります。これは、候補ハッシュのどのバイトも保存されたハッシュと一致しないことを示しています。数回試行した後、ハッシュ比較の1つに20nsがかかります。これは、候補ハッシュの最初のバイトが保存されているハッシュと一致することを示しています。上記の例では、これは攻撃者がハッシュの最初のバイトEk8fAMjPhBo
がE
であると推定したことを示しています。
設計上のハッシュには、どのハッシュがどのパスワードに対応するかを予測できないという特性があります。たとえば、これはしないパスワードがs
で始まることを攻撃者に知らせます。ただし、攻撃者は事前に計算されたハッシュの大きなテーブル(aRainbow table)を持っているため、E
で始まる文字列にハッシュされる他のパスワードを検索できます。彼らは十分なハッシュを試した後、最終的にmemcmp()
に30nsを要する入力を取得します。これは、最初の2バイトが一致することを示し、ハッシュの最初の2バイトがEk
であると推定しました。ハッシュのすべてまたはほとんどを推定するまで、このプロセスを繰り返します。その時点で、彼らはパスワードを知っているか、従来のレインボーテーブル攻撃でパスワードを総当たりにすることができます。
これは少し仮説ですが、次の例のように、タイミング攻撃に関する多くの実用的な情報をネット上の他の場所で見つけることができます。
https://research.kudelskisecurity.com/2013/12/13/timing-attacks-part-1/
問題は、サイドチャネル攻撃は、yourシステムについて考えているどのアプリケーションでも実用的であると主張することではありません。
より良いポイントは、
サイドチャネル攻撃は、より多くの状況で可能になる傾向がありますほとんどの開発者が手放せないと考えることができるよりも。
どのような状況でも、信頼できるnoタイミング攻撃の機会があることを確信させるのはSOPとして安全な比較方法を単に使用するよりも、開発時にかなり多くの作業。より多くの作業は、より多くのコストとそれを誤解するより高いリスクの両方を意味します。
簡単に言えば、それはぶら下がっている果物です。 「セキュリティが重要なデータに対してmemcmp
を使用しない」というポリシーは、想像できるほとんどすべてのパラメータに対して「安全なときにmemcmp
を使用しても大丈夫」というポリシーよりも優れています。
異常に、あなたがあるマイクロ秒のCPU時間の何分の1かを削る一致しない比較の場合(通常、そもそも一般的なケースではありません!)は、適切なセキュリティ分析に費やす価値のある十分なお金を節約し、その事実を証明する多くのビジネスドキュメントを手にします。
(それでも、ムーアの法則に任せている間、コミックを読むだけでその分析を行うことができるので、CPUマイクロ秒を節約できます)。
これは、サイドチャネル攻撃のカテゴリに分類されます(RSAと同じ要件で、秘密キーを使用した実行時間は一定でなければなりません)。また、RAMが危険にさらされているとは限りません。操作はTEE(信頼された実行環境)で実行できます。