web-dev-qa-db-ja.com

パスワードハッシュの検証を時定数にする必要があるのはなぜですか?

Asp.netコア PasswordHasher タイプにVerifyHashedPasswordメソッドに関するコメントがあります

 /// <remarks>Implementations of this method should be time consistent.</remarks>

そして、ハッシュを比較するために、意図的に最適化されていないコードを使用し、ループの早期終了を行わないようにします。

// Compares two byte arrays for equality. The method is specifically written so that the loop is not optimized.
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
private static bool ByteArraysEqual(byte[] a, byte[] b)
{
    if (a == null && b == null)
    {
        return true;
    }
    if (a == null || b == null || a.Length != b.Length)
    {
        return false;
    }
    var areSame = true;
    for (var i = 0; i < a.Length; i++)
    {
       areSame &= (a[i] == b[i]);
    }
    return areSame;
}

最初は、このタイミングがなければ、ハッシュがどれだけ近いかを判断するために使用できると思いました。時間がかかる場合、ハッシュの多くは同じです。

ただし、この時点でハッシュはSHA256の1000回の反復を経ているため、これは意味がありません。したがって、パスワードを変更すると、完全に異なるハッシュが生成され、パスワードがほぼ正しいハッシュを生成することを知っていても、正しいハッシュを見つけるのに役立ちません。

一定時間のハッシュ検証を保証する目的は何ですか?

29
trampster

どちらのハッシュも秘密ではなく、ハッシュが安全である(SHA-256は安全である)と仮定すると、一定時間内にハッシュをチェックする理由はありません。実際、ハッシュの比較は、一定時間のルーチン内でパスワードを検証するためのよく知られた代替手段の1つです。開発者がこれを行う理由を説明することはできませんが、技術的に一定の時間にする必要はありません。ほとんどの場合、彼らはただ用心していた。暗号化ライブラリに含まれる非定数のタイムコードは、監査人を不安にさせます。

理論的な弱点についての詳細は、暗号サイトで議論されています 回答でsignificantクエリの量で、ハッシュの最初の数バイトを発見することが可能であり、それにより、明らかに一致しない候補のパスワードを破棄するためのオフライン計算(ハッシュは実際のハッシュの最初の数バイトと一致しません)をパスワードチェックサービスに送信しないようにします。これが本当の問題ではない理由です。

42
forest