コンテンツへスキップ
uencoder

秘密情報の検証に定数時間比較を使う

秘密(パスワード、トークン、MAC)を比較するときは、値に依存しない一定時間で比較しないとタイミング側信道が生じます。その対策を学びましょう。

  1. 1

    一定時間比較は、不一致がどこで起きたかに関係なく、すべてのバイトを処理します。XOR と OR で差分を累積し、最後に累積値を確認します。これにより、攻撃者が実行時間から何バイト一致したかを知ることを防ぎます。

  2. 2
    ハッシュ比較ツール →

    2 つのハッシュ値を一定時間比較で比較します。ツールは、一致位置に関係なく、常に両方の入力のすべてのバイトを処理します。HMAC、パスワードハッシュ、API トークンの検証に使ってください。

  3. 3
    HMAC ジェネレーター →

    HMAC を生成した後、一定時間比較で検証します。パターンは、expected = HMAC(key, message) を計算し、その後 constantTimeEqual(expected, received) を呼びます。この比較に === や != を使わないでください。

  4. 4

    Node.js では crypto.timingSafeEqual(a, b) を使います。ブラウザーでは手動で実装します。すべてのバイトの XOR を累積し、結果を確認します。両方の入力は同じ長さでなければなりません。長さが異なる場合は即座に false を返してください(長さはシークレットではありません)。比較自体が一定時間である必要があるのは、長さが一致する場合だけです。

よくある質問

長さが異なる場合はどうしますか?
即座に false を返します。ハッシュやトークンの長さは通常シークレットではありません(アルゴリズムで固定されています)。一定時間という要件は、同じ長さの入力のバイト単位比較にのみ適用されます。異なる長さの値を一定時間で比較する必要はありません。
ネットワーク経由でもこれは重要ですか?
はい。タイミング攻撃は、約 15 ミリ秒のジッターがあるネットワーク経由でも実証されています。ローカルより難しいですが、十分なサンプル数があれば実行可能です。高価値のターゲット(API キー、決済トークン)では、ネットワーク経由でも常に一定時間比較を使ってください。

このタスクを解決するワークフロー

関連ツール